diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d51df20e15..94c2252ef73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ All notable changes for each version of this project will be documented in this ### Behavioral Changes +- `IgxComboComponent`, `IgxSimpleComboComponent`, `IgxDropDownComponent` and `IgxSelectComponent` + - The components, their items and groups now use `ChangeDetectionStrategy.OnPush`. Properties set from code still update the view, and combo records mutated in place still render on the next host check. - **Theming** - Scrollbar arrow buttons cannot be styled or enabled through the standard properties, and `scrollbar-width: thin` removes them where the platform draws them. - **Firefox** - The `scrollbar-color` and `scrollbar-width` properties are not supported on Firefox versions prior to 64, so the scrollbars in those versions will render with the platform default colors and size. diff --git a/my-changes.patch b/my-changes.patch new file mode 100644 index 00000000000..289649d81da --- /dev/null +++ b/my-changes.patch @@ -0,0 +1,111 @@ +diff --git a/projects/igniteui-angular-performance/src/app/app.routes.ts b/projects/igniteui-angular-performance/src/app/app.routes.ts +index 5804152b12..2ae1c41a32 100644 +--- a/projects/igniteui-angular-performance/src/app/app.routes.ts ++++ b/projects/igniteui-angular-performance/src/app/app.routes.ts +@@ -3,8 +3,15 @@ import { GridComponent } from './grid/grid.component'; + import { TreeGridComponent } from './tree-grid/tree-grid.component'; + import { PivotGridComponent } from './pivot-grid/pivot-grid.component'; + import { HierarchicalGridComponent } from './hierarchical-grid/hierarchical-grid.component'; ++import { ComboGridComponent } from './combo-grid/combo-grid.component'; + + export const routes: Routes = [ ++ { ++ path: "combo-grid-1m", ++ title: "Combo & Grid 1M records", ++ component: ComboGridComponent, ++ data: { rows: 1_000_000 } ++ }, + { + path: "pivot-grid", + title: "Pivot Grid", +diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-virtualization.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-virtualization.ts +index ac0557e6f7..d661b2fb4f 100644 +--- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-virtualization.ts ++++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-virtualization.ts +@@ -68,17 +68,10 @@ export function createDropDownVirtualization( + class VirtualScrollVirtualization implements IgxDropDownVirtualization { + private readonly _disconnect = new Subject(); + +- /** The window last rendered, for answering whether an index has an element. */ +- private _rendered = { startIndex: 0, endIndex: -1 }; +- + constructor( + private _scroll: IgxVirtualScrollComponent, + private _ref: ElementRef +- ) { +- outputToObservable(this._scroll.stateChange) +- .pipe(takeUntil(this._disconnect)) +- .subscribe(state => this._rendered = state); +- } ++ ) { } + + public get length(): number { + const window = this._scroll.dataWindow(); +@@ -115,8 +108,13 @@ class VirtualScrollVirtualization implements IgxDropDownVirtualization { + return found < 0 ? -1 : found + (window?.startIndex ?? 0); + } + ++ /** ++ * The rendered rows are the authority. `stateChange` reports the range the viewport ++ * wants, which over a paged collection reaches past the rows that have arrived, so a ++ * cached copy of it would answer for indices that have no element. ++ */ + public isIndexRendered(index: number): boolean { +- return index >= this._rendered.startIndex && index <= this._rendered.endIndex; ++ return !!this._ref.nativeElement.querySelector(`[data-vs-index="${index}"]`); + } + + /** +diff --git a/projects/igniteui-angular/virtual-scroll/src/virtual-scroll/virtual-scroll.component.spec.ts b/projects/igniteui-angular/virtual-scroll/src/virtual-scroll/virtual-scroll.component.spec.ts +index e5354845d7..4b3f93fe55 100644 +--- a/projects/igniteui-angular/virtual-scroll/src/virtual-scroll/virtual-scroll.component.spec.ts ++++ b/projects/igniteui-angular/virtual-scroll/src/virtual-scroll/virtual-scroll.component.spec.ts +@@ -1133,6 +1133,48 @@ describe('IgxVirtualScrollComponent', () => { + .toContain(`Item ${wanted.startIndex}`); + }); + ++ it('should report a page that lands inside an unchanged range', async () => { ++ // The list scrolls into a hole and reports the range it needs. The page that ++ // arrives fills that hole without moving anything: the wanted range, the ++ // viewport, and the total size all stay exactly as they were, because the rows ++ // measure at the estimate. The consumer naming rendered rows for assistive ++ // technology hears about them through this report and nothing else. ++ await bindWindow(windowHost.pageAt(0)); ++ await windowScroll.scrollToIndex(400); ++ await settle(windowFixture, windowScroll); ++ expect(vsItems(windowFixture).length).toBe(0); ++ ++ const wanted = windowHost.states.at(-1)!; ++ windowHost.states.length = 0; ++ ++ const count = wanted.endIndex - wanted.startIndex + 1; ++ await bindWindow(windowHost.pageAt(wanted.startIndex, count)); ++ ++ expect(vsIndices(windowFixture)).toContain(wanted.startIndex); ++ expect(windowHost.states.length).toBeGreaterThan(0); ++ expect(windowHost.states.at(-1)!.startIndex).toBe(wanted.startIndex); ++ }); ++ ++ it('should report again after the data was cleared and reloaded unchanged', async () => { ++ // Clearing everything and reloading the same page lands the list back in the ++ // exact state it reported before the clear. The consumer heard the list go ++ // empty, so the reload has to be told even though nothing about it is new. ++ await bindWindow(windowHost.pageAt(0)); ++ const before = windowHost.states.at(-1)!; ++ ++ windowHost.window.set(null); ++ windowHost.items.set([]); ++ await settle(windowFixture, windowScroll); ++ expect(vsItems(windowFixture).length).toBe(0); ++ windowHost.states.length = 0; ++ ++ await bindWindow(windowHost.pageAt(0)); ++ ++ expect(windowHost.states.length).toBeGreaterThan(0); ++ expect(windowHost.states.at(-1)!.startIndex).toBe(before.startIndex); ++ expect(windowHost.states.at(-1)!.endIndex).toBe(before.endIndex); ++ }); ++ + it('should report a moved range whose loaded part has not changed', async () => { + // Two loaded rows, and a viewport that reaches well past both of them. Moving + // one row down changes the range the consumer is being asked for, while the diff --git a/projects/igniteui-angular-performance/src/app/app.routes.ts b/projects/igniteui-angular-performance/src/app/app.routes.ts index 5804152b12b..2ae1c41a325 100644 --- a/projects/igniteui-angular-performance/src/app/app.routes.ts +++ b/projects/igniteui-angular-performance/src/app/app.routes.ts @@ -3,8 +3,15 @@ import { GridComponent } from './grid/grid.component'; import { TreeGridComponent } from './tree-grid/tree-grid.component'; import { PivotGridComponent } from './pivot-grid/pivot-grid.component'; import { HierarchicalGridComponent } from './hierarchical-grid/hierarchical-grid.component'; +import { ComboGridComponent } from './combo-grid/combo-grid.component'; export const routes: Routes = [ + { + path: "combo-grid-1m", + title: "Combo & Grid 1M records", + component: ComboGridComponent, + data: { rows: 1_000_000 } + }, { path: "pivot-grid", title: "Pivot Grid", diff --git a/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.html b/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.html new file mode 100644 index 00000000000..f4434ed2312 --- /dev/null +++ b/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.html @@ -0,0 +1,39 @@ +
+ + + + + The grid below filters with the Excel style menu. Open it on + UniqueValue to list {{ rows }} distinct entries. + +
+ +
+ + @for (col of columns; track col) { + + + } + +
diff --git a/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.scss b/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.scss new file mode 100644 index 00000000000..a81eb48f64c --- /dev/null +++ b/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.scss @@ -0,0 +1,19 @@ +:host { + display: flex; + flex-direction: column; + height: 100%; + gap: 8px; +} + +.combo-row { + display: flex; + align-items: center; + gap: 12px; + flex: 0 0 auto; +} + +.grid-wrapper { + flex: 1 1 auto; + min-height: 0; + width: 100%; +} diff --git a/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.ts b/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.ts new file mode 100644 index 00000000000..12f7c88a8cd --- /dev/null +++ b/projects/igniteui-angular-performance/src/app/combo-grid/combo-grid.component.ts @@ -0,0 +1,57 @@ +import { ChangeDetectionStrategy, Component, inject, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { GridColumnDataType, IGX_GRID_DIRECTIVES, IgxGridComponent } from 'igniteui-angular'; +import { IgxComboComponent } from 'igniteui-angular'; +import { DataService } from '../services/data.service'; + +/** One combo entry, kept small so a million of them stay affordable. */ +interface ComboRecord { + id: number; + name: string; +} + +@Component({ + selector: 'app-combo-grid', + imports: [IGX_GRID_DIRECTIVES, IgxComboComponent], + templateUrl: './combo-grid.component.html', + changeDetection: ChangeDetectionStrategy.Eager, + styleUrl: './combo-grid.component.scss' +}) +export class ComboGridComponent { + protected columns: any[] = []; + protected data: any[] = []; + protected comboData: ComboRecord[] = []; + protected rows: number; + + private dataService = inject(DataService); + private activatedRoute = inject(ActivatedRoute); + + @ViewChild(IgxGridComponent, { static: true }) + public grid!: IgxGridComponent; + + constructor() { + this.rows = this.activatedRoute.snapshot.data.rows; + + this.data = this.dataService.generateData(this.rows); + // A value per row and no two alike, so opening the Excel filter on this column has + // to list the whole collection rather than a handful of repeated entries. + this.data.forEach((row, index) => row.UniqueValue = index); + + this.comboData = Array.from({ length: this.rows }, (_, index) => ({ + id: index, + name: `Item ${index}` + })); + + this.columns = [ + { field: 'UniqueValue', dataType: GridColumnDataType.Number, sortable: true, width: 'auto', groupable: false }, + { field: 'Name', dataType: GridColumnDataType.String, sortable: true, width: 'auto', groupable: true }, + { field: 'AthleteNumber', dataType: GridColumnDataType.Number, sortable: true, width: 'auto', groupable: true }, + { field: 'CountryName', dataType: GridColumnDataType.String, sortable: true, width: 'auto', groupable: true }, + { field: 'Registered', dataType: GridColumnDataType.DateTime, sortable: true, width: 'auto', groupable: true }, + { field: 'Active', dataType: GridColumnDataType.Boolean, sortable: true, width: 'auto', groupable: true }, + { field: 'NetWorth', dataType: GridColumnDataType.Currency, sortable: true, width: 'auto', groupable: true }, + { field: 'SuccessRate', dataType: GridColumnDataType.Percent, sortable: true, width: 'auto', groupable: true }, + { field: 'Position', dataType: GridColumnDataType.String, sortable: true, width: 'auto', groupable: true } + ]; + } +} diff --git a/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts b/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts index 9cc1aded856..bcd484b723c 100644 --- a/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts +++ b/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts @@ -1,5 +1,5 @@ import { IgxComboItemComponent } from './combo-item.component'; -import { Component, HostBinding, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; /** * @hidden @@ -7,11 +7,13 @@ import { Component, HostBinding, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'igx-combo-add-item', template: '', - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '[class.igx-drop-down__item]': 'isDropDownItem' + }, providers: [{ provide: IgxComboItemComponent, useExisting: IgxComboAddItemComponent }], }) export class IgxComboAddItemComponent extends IgxComboItemComponent { - @HostBinding('class.igx-drop-down__item') public get isDropDownItem(): boolean { return false; } diff --git a/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts b/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts index 4c3c5ac884f..549dcba3aa2 100644 --- a/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts +++ b/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts @@ -1,4 +1,4 @@ -import { Component, QueryList, OnDestroy, AfterViewInit, ContentChildren, Input, booleanAttribute, inject, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { Component, QueryList, OnDestroy, AfterViewInit, ContentChildren, Input, booleanAttribute, inject, signal, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; import { IgxComboBase, IGX_COMBO_COMPONENT } from './combo.common'; import { IgxComboAddItemComponent } from './combo-add-item.component'; import { IgxComboAPIService } from './combo.api'; @@ -13,16 +13,23 @@ import { DropDownActionKey, IDropDownBase, IGX_DROPDOWN_BASE, IgxDropDownCompone styleUrl: '../../../drop-down/src/drop-down/drop-down.component.css', encapsulation: ViewEncapsulation.None, providers: [{ provide: IGX_DROPDOWN_BASE, useExisting: IgxComboDropDownComponent }], - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, imports: [IgxToggleDirective] }) export class IgxComboDropDownComponent extends IgxDropDownComponent implements IDropDownBase, OnDestroy, AfterViewInit { public combo = inject(IGX_COMBO_COMPONENT); protected comboAPI = inject(IgxComboAPIService); + private readonly _singleMode = signal(false); /** @hidden @internal */ @Input({ transform: booleanAttribute }) - public singleMode = false; + public get singleMode(): boolean { + return this._singleMode(); + } + + public set singleMode(value: boolean) { + this._singleMode.set(value); + } /** * @hidden diff --git a/projects/igniteui-angular/combo/src/combo/combo-item.component.ts b/projects/igniteui-angular/combo/src/combo/combo-item.component.ts index 9e149770e24..8767498f67a 100644 --- a/projects/igniteui-angular/combo/src/combo/combo-item.component.ts +++ b/projects/igniteui-angular/combo/src/combo/combo-item.component.ts @@ -1,9 +1,10 @@ import { Component, - HostBinding, Input, booleanAttribute, inject, + linkedSignal, + signal, ChangeDetectionStrategy } from '@angular/core'; import { IgxComboAPIService } from './combo.api'; @@ -15,12 +16,19 @@ import { IgxDropDownItemComponent, Navigate } from 'igniteui-angular/drop-down'; @Component({ selector: 'igx-combo-item', templateUrl: 'combo-item.component.html', - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '[style.height.rem]': '_itemHeightToRem', + '[attr.aria-label]': 'ariaLabel' + }, imports: [IgxCheckboxComponent] }) export class IgxComboItemComponent extends IgxDropDownItemComponent { protected comboAPI = inject(IgxComboAPIService); - + private readonly _itemHeight = signal(''); + private readonly _singleMode = signal(undefined!); + private readonly _selectionState = linkedSignal(() => + this.value != null && this.comboAPI.is_item_selected(this.itemID)); /** * Gets the height of a list item @@ -28,17 +36,21 @@ export class IgxComboItemComponent extends IgxDropDownItemComponent { * @hidden */ @Input() - public itemHeight: string | number = ''; + public get itemHeight(): string | number { + return this._itemHeight(); + } + + public set itemHeight(value: string | number) { + this._itemHeight.set(value); + } /** @hidden @internal */ - @HostBinding('style.height.rem') public get _itemHeightToRem() { if (this.itemHeight) { return rem(this.itemHeight); } } - @HostBinding('attr.aria-label') @Input() public override get ariaLabel(): string { const valueKey = this.comboAPI.valueKey; @@ -47,7 +59,13 @@ export class IgxComboItemComponent extends IgxDropDownItemComponent { /** @hidden @internal */ @Input({ transform: booleanAttribute }) - public singleMode!: boolean; + public get singleMode(): boolean { + return this._singleMode(); + } + + public set singleMode(value: boolean) { + this._singleMode.set(value); + } /** * @hidden @@ -69,23 +87,22 @@ export class IgxComboItemComponent extends IgxDropDownItemComponent { * @internal */ public override ngDoCheck(): void { - // Sync state from services once per CD cycle so template bindings return stable field values - this._selected = !this.isHeader && this.value != null && this.comboAPI.is_item_selected(this.itemID); - this._disableTransitions = this.comboAPI.disableTransitions; + // Re-resolved on each check, since keys can change in place; skips the base reconciliation. + this._selectionState.set(!this.isHeader && this.value != null && this.comboAPI.is_item_selected(this.itemID)); } /** * @hidden */ public override get selected(): boolean { - return this._selected; + return !this.isHeader && this._selectionState(); } public override set selected(value: boolean) { if (this.isHeader) { return; } - this._selected = value; + this._selectionState.set(value); } /** @@ -93,11 +110,9 @@ export class IgxComboItemComponent extends IgxDropDownItemComponent { * @internal */ public get disableTransitions() { - return this._disableTransitions; + return this.comboAPI.disableTransitions; } - private _disableTransitions = false; - /** * @hidden */ diff --git a/projects/igniteui-angular/combo/src/combo/combo.api.ts b/projects/igniteui-angular/combo/src/combo/combo.api.ts index e0f67630fff..3e6e1305123 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.api.ts +++ b/projects/igniteui-angular/combo/src/combo/combo.api.ts @@ -1,13 +1,21 @@ import { IgxComboBase } from './combo.common'; -import { Injectable } from '@angular/core'; +import { Injectable, signal } from '@angular/core'; /** * @hidden */ @Injectable() export class IgxComboAPIService { - public disableTransitions = false; + public get disableTransitions(): boolean { + return this._disableTransitions(); + } + + public set disableTransitions(value: boolean) { + this._disableTransitions.set(value); + } + protected combo!: IgxComboBase; + private readonly _disableTransitions = signal(false); public get valueKey() { return this.combo.valueKey !== null && this.combo.valueKey !== undefined ? this.combo.valueKey : null; diff --git a/projects/igniteui-angular/combo/src/combo/combo.common.ts b/projects/igniteui-angular/combo/src/combo/combo.common.ts index fcf5435467c..410c9b8cf15 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.common.ts +++ b/projects/igniteui-angular/combo/src/combo/combo.common.ts @@ -1,16 +1,12 @@ import { AfterContentChecked, - AfterViewChecked, AfterViewInit, booleanAttribute, ChangeDetectorRef, - ContentChild, - ContentChildren, Directive, ElementRef, EventEmitter, forwardRef, - HostBinding, InjectionToken, Injector, Input, @@ -19,10 +15,16 @@ import { Output, QueryList, TemplateRef, - ViewChild, DOCUMENT, - ViewChildren, - inject + inject, + signal, + computed, + ViewChild, + viewChild, + contentChild, + contentChildren, + viewChildren, + linkedSignal } from '@angular/core'; import { ControlValueAccessor, NgControl } from '@angular/forms'; import { caseSensitive } from '@igniteui/material-icons-extended'; @@ -108,8 +110,14 @@ export interface IComboFilteringOptions { filteringKey?: string; } -@Directive() -export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewChecked, OnInit, +@Directive({ + host: { + '[attr.id]': 'id', + '[style.width]': 'width', + '[class.igx-combo]': 'cssClass' + } +}) +export abstract class IgxComboBaseDirective implements IgxComboBase, OnInit, AfterViewInit, AfterContentChecked, OnDestroy, ControlValueAccessor { protected elementRef = inject(ElementRef); protected cdr = inject(ChangeDetectorRef); @@ -134,7 +142,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input({ transform: booleanAttribute }) - public showSearchCaseIcon = false; + public get showSearchCaseIcon(): boolean { + return this.showSearchCaseIconState(); + } + public set showSearchCaseIcon(value: boolean) { + this.showSearchCaseIconState.set(value); + } + private readonly showSearchCaseIconState = signal(false); /** * Enables/disables filtering in the list. The default is `false`. @@ -179,7 +193,6 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @HostBinding('attr.id') @Input() public get id(): string { return this._id; @@ -210,9 +223,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @HostBinding('style.width') @Input() - public width!: string; + public get width(): string { + return this.widthState(); + } + public set width(value: string) { + this.widthState.set(value); + } + private readonly widthState = signal(undefined!); /** * Controls whether custom values can be added to the collection @@ -228,7 +246,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input({ transform: booleanAttribute }) - public allowCustomValues = false; + public get allowCustomValues(): boolean { + return this.allowCustomValuesState(); + } + public set allowCustomValues(value: boolean) { + this.allowCustomValuesState.set(value); + } + private readonly allowCustomValuesState = signal(false); /** * Configures the drop down list height @@ -298,7 +322,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public itemsWidth!: string; + public get itemsWidth(): string { + return this.itemsWidthState(); + } + public set itemsWidth(value: string) { + this.itemsWidthState.set(value); + } + private readonly itemsWidthState = signal(undefined!); /** * Defines the placeholder value for the combo value field @@ -314,7 +344,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public placeholder!: string; + public get placeholder(): string { + return this.placeholderState(); + } + public set placeholder(value: string) { + this.placeholderState.set(value); + } + private readonly placeholderState = signal(undefined!); /** * Combo data source. @@ -352,7 +388,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public valueKey: string = null!; + public get valueKey(): string { + return this.valueKeyState(); + } + public set valueKey(value: string) { + this.valueKeyState.set(value); + } + private readonly valueKeyState = signal(null!); @Input() public set displayKey(val: string) { @@ -433,7 +475,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public filterFunction!: (collection: any[], searchValue: any, filteringOptions: IComboFilteringOptions) => any[]; + public get filterFunction(): (collection: any[], searchValue: any, filteringOptions: IComboFilteringOptions) => any[] { + return this.filterFunctionState(); + } + public set filterFunction(value: (collection: any[], searchValue: any, filteringOptions: IComboFilteringOptions) => any[]) { + this.filterFunctionState.set(value); + } + private readonly filterFunctionState = signal<(collection: any[], searchValue: any, filteringOptions: IComboFilteringOptions) => any[]>(undefined!); /** * Sets aria-labelledby attribute value. @@ -442,11 +490,22 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public ariaLabelledBy!: string; + public get ariaLabelledBy(): string { + return this.ariaLabelledByState(); + } + public set ariaLabelledBy(value: string) { + this.ariaLabelledByState.set(value); + } + private readonly ariaLabelledByState = signal(undefined!); /** @hidden @internal */ - @HostBinding('class.igx-combo') - public cssClass = 'igx-combo'; // Independent of display density for the time being + public get cssClass(): string { + return this.cssClassState(); + } + public set cssClass(value: string) { + this.cssClassState.set(value); + } + private readonly cssClassState = signal('igx-combo'); // Independent of display density for the time being /** * Disables the combo. The default is `false`. @@ -455,7 +514,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input({ transform: booleanAttribute }) - public disabled = false; + public get disabled(): boolean { + return this.disabledState(); + } + public set disabled(value: boolean) { + this.disabledState.set(value); + } + private readonly disabledState = signal(false); /** * Disables the clear button. The default is `false`. @@ -471,7 +536,13 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input({ transform: booleanAttribute }) - public disableClear = false; + public get disableClear(): boolean { + return this.disableClearState(); + } + public set disableClear(value: boolean) { + this.disableClearState.set(value); + } + private readonly disableClearState = signal(false); /** * Sets the visual combo type. @@ -595,8 +666,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboItemDirective, { read: TemplateRef }) - public itemTemplate: TemplateRef = null!; + public get itemTemplate(): TemplateRef { + return this.itemTemplateState(); + } + public set itemTemplate(value: TemplateRef) { + this.itemTemplateState.set(value); + } + private readonly itemTemplateQuery = contentChild>(IgxComboItemDirective, { read: TemplateRef }); + private readonly itemTemplateState = linkedSignal>(() => this.itemTemplateQuery() ?? undefined!); /** * The custom template, if any, that should be used when rendering the HEADER for the combo items list @@ -618,8 +695,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboHeaderDirective, { read: TemplateRef }) - public headerTemplate: TemplateRef = null!; + public get headerTemplate(): TemplateRef { + return this.headerTemplateState(); + } + public set headerTemplate(value: TemplateRef) { + this.headerTemplateState.set(value); + } + private readonly headerTemplateQuery = contentChild>(IgxComboHeaderDirective, { read: TemplateRef }); + private readonly headerTemplateState = linkedSignal>(() => this.headerTemplateQuery() ?? undefined!); /** * The custom template, if any, that should be used when rendering the FOOTER for the combo items list @@ -641,8 +724,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboFooterDirective, { read: TemplateRef }) - public footerTemplate: TemplateRef = null!; + public get footerTemplate(): TemplateRef { + return this.footerTemplateState(); + } + public set footerTemplate(value: TemplateRef) { + this.footerTemplateState.set(value); + } + private readonly footerTemplateQuery = contentChild>(IgxComboFooterDirective, { read: TemplateRef }); + private readonly footerTemplateState = linkedSignal>(() => this.footerTemplateQuery() ?? undefined!); /** * The custom template, if any, that should be used when rendering HEADER ITEMS for groups in the combo list @@ -662,8 +751,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboHeaderItemDirective, { read: TemplateRef }) - public headerItemTemplate: TemplateRef = null!; + public get headerItemTemplate(): TemplateRef { + return this.headerItemTemplateState(); + } + public set headerItemTemplate(value: TemplateRef) { + this.headerItemTemplateState.set(value); + } + private readonly headerItemTemplateQuery = contentChild>(IgxComboHeaderItemDirective, { read: TemplateRef }); + private readonly headerItemTemplateState = linkedSignal>(() => this.headerItemTemplateQuery() ?? undefined!); /** * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down @@ -685,8 +780,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboAddItemDirective, { read: TemplateRef }) - public addItemTemplate: TemplateRef = null!; + public get addItemTemplate(): TemplateRef { + return this.addItemTemplateState(); + } + public set addItemTemplate(value: TemplateRef) { + this.addItemTemplateState.set(value); + } + private readonly addItemTemplateQuery = contentChild>(IgxComboAddItemDirective, { read: TemplateRef }); + private readonly addItemTemplateState = linkedSignal>(() => this.addItemTemplateQuery() ?? undefined!); /** * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down @@ -708,8 +809,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboEmptyDirective, { read: TemplateRef }) - public emptyTemplate: TemplateRef = null!; + public get emptyTemplate(): TemplateRef { + return this.emptyTemplateState(); + } + public set emptyTemplate(value: TemplateRef) { + this.emptyTemplateState.set(value); + } + private readonly emptyTemplateQuery = contentChild>(IgxComboEmptyDirective, { read: TemplateRef }); + private readonly emptyTemplateState = linkedSignal>(() => this.emptyTemplateQuery() ?? undefined!); /** * The custom template, if any, that should be used when rendering the combo TOGGLE(open/close) button @@ -729,8 +836,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboToggleIconDirective, { read: TemplateRef }) - public toggleIconTemplate: TemplateRef = null!; + public get toggleIconTemplate(): TemplateRef { + return this.toggleIconTemplateState(); + } + public set toggleIconTemplate(value: TemplateRef) { + this.toggleIconTemplateState.set(value); + } + private readonly toggleIconTemplateQuery = contentChild>(IgxComboToggleIconDirective, { read: TemplateRef }); + private readonly toggleIconTemplateState = linkedSignal>(() => this.toggleIconTemplateQuery() ?? undefined!); /** * The custom template, if any, that should be used when rendering the combo CLEAR button @@ -750,23 +863,54 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * * ``` */ - @ContentChild(IgxComboClearIconDirective, { read: TemplateRef }) - public clearIconTemplate: TemplateRef = null!; + public get clearIconTemplate(): TemplateRef { + return this.clearIconTemplateState(); + } + public set clearIconTemplate(value: TemplateRef) { + this.clearIconTemplateState.set(value); + } + private readonly clearIconTemplateQuery = contentChild>(IgxComboClearIconDirective, { read: TemplateRef }); + private readonly clearIconTemplateState = linkedSignal>(() => this.clearIconTemplateQuery() ?? undefined!); /** @hidden @internal */ - @ContentChild(forwardRef(() => IgxLabelDirective), { static: true }) public label?: IgxLabelDirective; + public get label(): IgxLabelDirective | undefined { + return this.labelState(); + } + public set label(value: IgxLabelDirective | undefined) { + this.labelState.set(value); + } + private readonly labelQuery = contentChild(forwardRef(() => IgxLabelDirective)); + private readonly labelState = linkedSignal(() => this.labelQuery()); /** @hidden @internal */ - @ViewChild('inputGroup', { read: IgxInputGroupComponent, static: true }) - public inputGroup!: IgxInputGroupComponent; + public get inputGroup(): IgxInputGroupComponent { + return this.inputGroupState(); + } + public set inputGroup(value: IgxInputGroupComponent) { + this.inputGroupState.set(value); + } + private readonly inputGroupQuery = viewChild('inputGroup', { read: IgxInputGroupComponent }); + private readonly inputGroupState = linkedSignal(() => this.inputGroupQuery() ?? undefined!); /** @hidden @internal */ - @ViewChild('comboInput', { read: IgxInputDirective, static: true }) - public comboInput!: IgxInputDirective; + public get comboInput(): IgxInputDirective { + return this.comboInputState(); + } + public set comboInput(value: IgxInputDirective) { + this.comboInputState.set(value); + } + private readonly comboInputQuery = viewChild('comboInput', { read: IgxInputDirective }); + private readonly comboInputState = linkedSignal(() => this.comboInputQuery() ?? undefined!); /** @hidden @internal */ - @ViewChild('searchInput') - public searchInput: ElementRef = null!; + public get searchInput(): ElementRef { + return this.searchInputState(); + } + public set searchInput(value: ElementRef) { + this.searchInputState.set(value); + } + private readonly searchInputQuery = viewChild>('searchInput'); + private readonly searchInputState = linkedSignal>(() => this.searchInputQuery() ?? undefined!); /** @hidden @internal */ @ViewChild(IgxForOfDirective, { static: true }) @@ -775,26 +919,47 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh @ViewChild(IgxForOfDirective, { read: IgxForOfDirective, static: true }) protected virtDir!: IgxForOfDirective; - @ViewChild('dropdownItemContainer', { static: true }) - protected dropdownContainer: ElementRef = null!; + protected get dropdownContainer(): ElementRef { + return this.dropdownContainerState(); + } + protected set dropdownContainer(value: ElementRef) { + this.dropdownContainerState.set(value); + } + private readonly dropdownContainerQuery = viewChild('dropdownItemContainer'); + private readonly dropdownContainerState = linkedSignal(() => this.dropdownContainerQuery() ?? undefined!); - @ViewChild('primitive', { read: TemplateRef, static: true }) - protected primitiveTemplate!: TemplateRef; + protected get primitiveTemplate(): TemplateRef { + return this.primitiveTemplateState(); + } + protected set primitiveTemplate(value: TemplateRef) { + this.primitiveTemplateState.set(value); + } + private readonly primitiveTemplateQuery = viewChild>('primitive', { read: TemplateRef }); + private readonly primitiveTemplateState = linkedSignal>(() => this.primitiveTemplateQuery() ?? undefined!); - @ViewChild('complex', { read: TemplateRef, static: true }) - protected complexTemplate!: TemplateRef; + protected get complexTemplate(): TemplateRef { + return this.complexTemplateState(); + } + protected set complexTemplate(value: TemplateRef) { + this.complexTemplateState.set(value); + } + private readonly complexTemplateQuery = viewChild>('complex', { read: TemplateRef }); + private readonly complexTemplateState = linkedSignal>(() => this.complexTemplateQuery() ?? undefined!); - @ContentChildren(IgxPrefixDirective, { descendants: true }) - protected prefixes!: QueryList; + private readonly prefixQuery = contentChildren(IgxPrefixDirective, { descendants: true }); + protected readonly prefixes = computed(() => this.asQueryList(this.prefixQuery())); - @ContentChildren(IgxSuffixDirective, { descendants: true }) - protected suffixes!: QueryList; + private readonly suffixQuery = contentChildren(IgxSuffixDirective, { descendants: true }); + protected readonly suffixes = computed(() => this.asQueryList(this.suffixQuery())); - @ContentChildren(IgxHintDirective, { descendants: true }) - protected contentHints!: QueryList; + private readonly hintQuery = contentChildren(IgxHintDirective, { descendants: true }); + protected readonly contentHints = computed(() => this.asQueryList(this.hintQuery())); - @ViewChildren(IgxSuffixDirective) - protected internalSuffixes!: QueryList; + private readonly internalSuffixQuery = viewChildren(IgxSuffixDirective); + protected readonly internalSuffixes = computed(() => this.asQueryList(this.internalSuffixQuery())); + private readonly mergedSuffixes = computed(() => this.asQueryList([ + ...this.suffixes(), ...this.internalSuffixes() + ])); /** @hidden @internal */ public get searchValue(): string { @@ -814,10 +979,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh /** @hidden @internal */ public get dataType(): string { - if (this.displayKey) { - return DataTypes.COMPLEX; - } - return DataTypes.PRIMITIVE; + return this.dataTypeState(); } /** @@ -928,24 +1090,41 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh /** @hidden @internal */ public get template(): TemplateRef { - this._dataType = this.dataType; if (this.itemTemplate) { return this.itemTemplate; } - if (this._dataType === DataTypes.COMPLEX) { + if (this.dataType === DataTypes.COMPLEX) { return this.complexTemplate; } return this.primitiveTemplate; } /** @hidden @internal */ - public customValueFlag = true; + public get customValueFlag(): boolean { + return this.customValueFlagState(); + } + public set customValueFlag(value: boolean) { + this.customValueFlagState.set(value); + } + private readonly customValueFlagState = signal(true); /** @hidden @internal */ - public filterValue = ''; + public get filterValue(): string { + return this.filterValueState(); + } + public set filterValue(value: string) { + this.filterValueState.set(value); + } + private readonly filterValueState = signal(''); /** @hidden @internal */ public defaultFallbackGroup = 'Other'; /** @hidden @internal */ - public activeDescendant = ''; + public get activeDescendant(): string { + return this.activeDescendantState(); + } + public set activeDescendant(value: string) { + this.activeDescendantState.set(value); + } + private readonly activeDescendantState = signal(''); /** * Configures the way combo items will be filtered. @@ -970,36 +1149,145 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh } protected containerSize: number | undefined = undefined; - protected itemSize = undefined; - protected _data: any[] = []; - protected _value: any[] = []; - protected _displayValue = ''; - protected _groupKey = ''; - protected _searchValue = ''; - protected _filteredData: any[] = []; - protected _displayKey!: string; + protected get itemSize(): number | undefined { + return this.itemSizeState(); + } + protected set itemSize(value: number | undefined) { + this.itemSizeState.set(value); + } + private readonly itemSizeState = signal(undefined); + protected get _data(): any[] { + return this.dataState(); + } + protected set _data(value: any[]) { + this.dataState.set(value); + } + private readonly dataState = signal([]); + protected get _value(): any[] { + return this.valueState(); + } + protected set _value(value: any[]) { + this.valueState.set(value); + } + private readonly valueState = signal([]); + protected get _displayValue(): string { + return this.displayValueState(); + } + protected set _displayValue(value: string) { + this.displayValueState.set(value); + } + private readonly displayValueState = signal(''); + protected get _groupKey(): string { + return this.groupKeyState(); + } + protected set _groupKey(value: string) { + this.groupKeyState.set(value); + } + private readonly groupKeyState = signal(''); + protected get _searchValue(): string { + return this.searchValueState(); + } + protected set _searchValue(value: string) { + this.searchValueState.set(value); + } + private readonly searchValueState = signal(''); + protected get _filteredData(): any[] { + return this.filteredDataState(); + } + protected set _filteredData(value: any[]) { + this.filteredDataState.set(value); + } + private readonly filteredDataState = signal([]); + protected get _displayKey(): string { + return this.displayKeyState(); + } + protected set _displayKey(value: string) { + this.displayKeyState.set(value); + } + private readonly displayKeyState = signal(undefined!); protected _remoteSelection = {}; - protected _resourceStrings: IComboResourceStrings = null!; - protected _customResourceStrings: IComboResourceStrings = getCurrentResourceStrings(ComboResourceStringsEN); - protected _defaultResourceStrings = getCurrentResourceStrings(ComboResourceStringsEN); + protected get _resourceStrings(): IComboResourceStrings { + return this.resourceStringsState(); + } + protected set _resourceStrings(value: IComboResourceStrings) { + this.resourceStringsState.set(value); + } + private readonly resourceStringsState = signal(null!); + protected get _customResourceStrings(): IComboResourceStrings { + return this.customResourceStringsState(); + } + protected set _customResourceStrings(value: IComboResourceStrings) { + this.customResourceStringsState.set(value); + } + private readonly customResourceStringsState = signal(getCurrentResourceStrings(ComboResourceStringsEN)); + protected get _defaultResourceStrings(): IComboResourceStrings { + return this.defaultResourceStringsState(); + } + protected set _defaultResourceStrings(value: IComboResourceStrings) { + this.defaultResourceStringsState.set(value); + } + private readonly defaultResourceStringsState = signal(getCurrentResourceStrings(ComboResourceStringsEN)); protected _valid = IgxInputState.INITIAL; protected ngControl: NgControl = null!; private control: NgControlAdapter | null = null; protected destroy$ = new Subject(); protected _onTouchedCallback: () => void = noop; protected _onChangeCallback: (_: any) => void = noop; + protected readonly selectionRevision = signal(0); + private readonly dataTypeState = computed(() => this.displayKey ? DataTypes.COMPLEX : DataTypes.PRIMITIVE); + protected compareCollator = new Intl.Collator(); protected computedStyles: any; - private _id: string = `igx-combo-${NEXT_ID++}`; - private _disableFiltering = false; - private _type: IgxInputGroupType | null = null; - private _dataType = ''; - private _itemHeight: number | undefined = undefined; - private _itemsMaxHeight: number | null = null; - private _overlaySettings!: OverlaySettings; - private _groupSortingDirection: SortingDirection = SortingDirection.Asc; - private _filteringOptions!: IComboFilteringOptions; + private get _id(): string { + return this.idState(); + } + private set _id(value: string) { + this.idState.set(value); + } + private readonly idState = signal(`igx-combo-${NEXT_ID++}`); + private get _disableFiltering(): boolean { + return this.disableFilteringState(); + } + private set _disableFiltering(value: boolean) { + this.disableFilteringState.set(value); + } + private readonly disableFilteringState = signal(false); + private get _type(): IgxInputGroupType | null { + return this.typeState(); + } + private set _type(value: IgxInputGroupType | null) { + this.typeState.set(value); + } + private readonly typeState = signal(null); + private get _itemHeight(): number | undefined { + return this.itemHeightState(); + } + private set _itemHeight(value: number | undefined) { + this.itemHeightState.set(value); + } + private readonly itemHeightState = signal(undefined); + private get _itemsMaxHeight(): number | null { + return this.itemsMaxHeightState(); + } + private set _itemsMaxHeight(value: number | null) { + this.itemsMaxHeightState.set(value); + } + private readonly itemsMaxHeightState = signal(null); + private get _groupSortingDirection(): SortingDirection { + return this.groupSortingDirectionState(); + } + private set _groupSortingDirection(value: SortingDirection) { + this.groupSortingDirectionState.set(value); + } + private readonly groupSortingDirectionState = signal(SortingDirection.Asc); + private get _filteringOptions(): IComboFilteringOptions { + return this.filteringOptionsState(); + } + private set _filteringOptions(value: IComboFilteringOptions) { + this.filteringOptionsState.set(value); + } + private readonly filteringOptionsState = signal(undefined!); private _defaultFilteringOptions: IComboFilteringOptions = { caseSensitive: false }; private itemsInContainer = 10; @@ -1014,13 +1302,19 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh }, this); } - public ngAfterViewChecked() { + private readonly _scrollStrategy = new AbsoluteScrollStrategy(); + private readonly _positionStrategy = new AutoPositionStrategy(); + + private get _overlaySettings(): OverlaySettings { + if (!this.inputGroup) { + return {}; + } const targetElement = this.inputGroup.element.nativeElement.querySelector('.igx-input-group__bundle') as HTMLElement; - this._overlaySettings = { + return { target: targetElement, - scrollStrategy: new AbsoluteScrollStrategy(), - positionStrategy: new AutoPositionStrategy(), + scrollStrategy: this._scrollStrategy, + positionStrategy: this._positionStrategy, modal: false, closeOnOutsideClick: true, excludeFromOutsideClick: [targetElement] @@ -1029,24 +1323,18 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh /** @hidden @internal */ public ngAfterContentChecked(): void { - if (this.inputGroup && this.prefixes?.length > 0) { - this.inputGroup.prefixes = this.prefixes; - } - if (this.inputGroup) { - const suffixesArray = this.suffixes?.toArray() ?? []; - const internalSuffixesArray = this.internalSuffixes?.toArray() ?? []; - const mergedSuffixes = new QueryList(); - mergedSuffixes.reset([ - ...suffixesArray, - ...internalSuffixesArray - ]); - this.inputGroup.suffixes = mergedSuffixes; + // The input group still takes QueryLists; each list is reused until its content changes. + this.inputGroup.prefixes = this.prefixes(); + this.inputGroup.suffixes = this.mergedSuffixes(); + this.inputGroup.hints = this.contentHints(); } + } - if (this.inputGroup) { - this.inputGroup.hints = this.contentHints; - } + private asQueryList(items: readonly T[]): QueryList { + const list = new QueryList(); + list.reset([...items]); + return list; } /** @hidden @internal */ @@ -1156,6 +1444,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ public get selection(): any[] { + this.selectionRevision(); const serviceRef = this.selectionService.get(this.id); return serviceRef ? this.convertKeysToItems(Array.from(serviceRef)) : []; } @@ -1167,9 +1456,11 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * @internal */ public isItemSelected(item: any): boolean { + this.selectionRevision(); return this.selectionService.is_item_selected(this.id, item); } + /** @hidden @internal */ public get toggleIcon(): string { return this.dropdown.collapsed ? 'input_expand' : 'input_collapse'; @@ -1339,6 +1630,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh } this.manageRequiredAsterisk(); + this.cdr.markForCheck(); }; private updateValidity() { diff --git a/projects/igniteui-angular/combo/src/combo/combo.component.html b/projects/igniteui-angular/combo/src/combo/combo.component.html index 31c42418165..4bc045a26b2 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.component.html +++ b/projects/igniteui-angular/combo/src/combo/combo.component.html @@ -55,7 +55,7 @@ @if (showSearchCaseIcon) { { }); }); + describe('Selection lookup', () => { + beforeEach(async () => { + TestBed.resetTestingModule(); + await TestBed.configureTestingModule({ + imports: [NoopAnimationsModule, IgxComboComponent], + providers: [provideZonelessChangeDetection()] + }).compileComponents(); + fixture = TestBed.createComponent(IgxComboComponent); + fixture.componentRef.setInput('valueKey', 'id'); + fixture.componentRef.setInput('displayKey', 'label'); + combo = fixture.componentInstance; + await fixture.whenStable(); + }); + + afterEach(() => { + fixture.destroy(); + // The combo overwrites the host id, so TestBed can't remove it. + fixture.nativeElement.remove(); + }); + + it('should render programmatic disabled state changes without forced change detection', async () => { + combo.setDisabledState(true); + await fixture.whenStable(); + expect(combo.getEditElement().hasAttribute('disabled')).toBeTrue(); + + combo.setDisabledState(false); + await fixture.whenStable(); + expect(combo.getEditElement().hasAttribute('disabled')).toBeFalse(); + }); + + it('should render a programmatic selection and clear without forced change detection', async () => { + fixture.componentRef.setInput('data', [{ id: 1, label: 'First' }, { id: 2, label: 'Second' }]); + await fixture.whenStable(); + + combo.select([1, 2]); + await fixture.whenStable(); + expect((combo.getEditElement() as HTMLInputElement).value).toBe('First, Second'); + expect(fixture.nativeElement.querySelector('.igx-combo__clear-button')).not.toBeNull(); + + combo.deselectAllItems(true); + await fixture.whenStable(); + expect((combo.getEditElement() as HTMLInputElement).value).toBe(''); + expect(fixture.nativeElement.querySelector('.igx-combo__clear-button')).toBeNull(); + }); + + it('should follow the total item count when detecting remote data', async () => { + fixture.componentRef.setInput('data', [{ id: 1, label: 'First' }, { id: 2, label: 'Second' }]); + await fixture.whenStable(); + // Read before a count arrives, where a cached result used to stick. + expect(combo.isRemote).toBeFalse(); + + combo.totalItemCount = 100; + await fixture.whenStable(); + expect(combo.isRemote).toBeTrue(); + + combo.totalItemCount = 0; + await fixture.whenStable(); + expect(combo.isRemote).toBeFalse(); + }); + }); describe('Resource Strings', () => { let fix: ComponentFixture; @@ -3818,6 +3878,130 @@ describe('igxCombo', () => { } }); }); + + describe('Mutable data reconciliation', () => { + let host: IgxComboMutableRecordsComponent; + + const rendered = (record: { id: number }) => + combo.dropdown.items.find(item => item.value === record); + const ariaSelected = (record: { id: number }) => + rendered(record).element.nativeElement.getAttribute('aria-selected'); + const renameFirstRecord = () => + (fixture.nativeElement.querySelector('.rename-first') as HTMLButtonElement).click(); + + beforeEach(async () => { + TestBed.resetTestingModule(); + await TestBed.configureTestingModule({ + imports: [NoopAnimationsModule, IgxComboMutableRecordsComponent], + providers: [provideZonelessChangeDetection()] + }).compileComponents(); + fixture = TestBed.createComponent(IgxComboMutableRecordsComponent); + host = fixture.componentInstance; + combo = host.combo; + await fixture.whenStable(); + }); + + it('should deselect an item whose record key changes in place', async () => { + const first = host.items[0]; + combo.select([1]); + combo.open(); + await fixture.whenStable(); + expect(rendered(first).selected).toBeTrue(); + expect(ariaSelected(first)).toBe('true'); + + renameFirstRecord(); + await fixture.whenStable(); + + expect(first.id).toBe(3); + expect(combo.isItemSelected(1)).toBeTrue(); + expect(combo.isItemSelected(3)).toBeFalse(); + expect(combo.selection).toEqual([{ id: 1 }]); + expect(rendered(first).selected).toBeFalse(); + expect(ariaSelected(first)).toBe('false'); + }); + + it('should render a displayed field changed in place once the consumer view is checked', async () => { + const second = host.items[1]; + const renderedText = () => rendered(second).element.nativeElement.textContent.trim(); + combo.open(); + await fixture.whenStable(); + expect(renderedText()).toBe('Two'); + + // Notify through a host signal; a DOM event would close the overlay. + second.text = 'Two changed'; + host.version.update(version => version + 1); + await fixture.whenStable(); + + expect(fixture.nativeElement.querySelector('.host-version').textContent).toBe('1'); + expect(combo.collapsed).toBeFalse(); + expect(renderedText()).toBe('Two changed'); + }); + it('should deselect it when a custom display text leaves the combo unchanged', async () => { + const first = host.items[0]; + host.displayText = 'Chosen'; + combo.select([1]); + combo.open(); + await fixture.whenStable(); + expect(combo.displayValue).toBe('Chosen'); + expect(ariaSelected(first)).toBe('true'); + + renameFirstRecord(); + await fixture.whenStable(); + + expect(combo.displayValue).toBe('Chosen'); + expect(combo.isItemSelected(3)).toBeFalse(); + expect(rendered(first).selected).toBeFalse(); + expect(ariaSelected(first)).toBe('false'); + }); + + it('should leave an item unselected when selectionChanging is cancelled', async () => { + const second = host.items[1]; + host.cancelSelection = true; + combo.open(); + await fixture.whenStable(); + + (rendered(second).element.nativeElement as HTMLElement).click(); + await fixture.whenStable(); + + expect(combo.selection).toEqual([]); + expect(combo.isItemSelected(2)).toBeFalse(); + expect(rendered(second).selected).toBeFalse(); + expect(ariaSelected(second)).toBe('false'); + }); + + it('should resolve recycled items against the records they hold while scrolling', async () => { + fixture.componentRef.setInput('items', + Array.from({ length: 50 }, (_, index) => ({ id: index + 1, text: `Item ${index + 1}` }))); + await fixture.whenStable(); + const first = host.items[0]; + const last = host.items[host.items.length - 1]; + combo.select([first.id, last.id]); + combo.open(); + await fixture.whenStable(); + const recycled = rendered(first); + expect(recycled.selected).toBeTrue(); + expect(ariaSelected(first)).toBe('true'); + + // A single scroll: right after opening, igxFor can drop a second scrollTo as a no-op. + const loaded = firstValueFrom(combo.virtualScrollContainer.chunkLoad); + combo.virtualScrollContainer.scrollTo(host.items.length - 1); + await loaded; + await fixture.whenStable(); + + expect(rendered(first)).toBeUndefined(); + expect(recycled.value).not.toBe(first); + expect(combo.isItemSelected(recycled.value.id)).toBeFalse(); + expect(recycled.selected).toBeFalse(); + expect(recycled.element.nativeElement.getAttribute('aria-selected')).toBe('false'); + for (const item of combo.dropdown.items) { + const selected = combo.isItemSelected(item.value.id); + expect(item.selected).withContext(item.value.text).toBe(selected); + expect(item.element.nativeElement.getAttribute('aria-selected')).withContext(item.value.text).toBe(`${selected}`); + } + expect(rendered(last).selected).toBeTrue(); + expect(ariaSelected(last)).toBe('true'); + }); + }); }); describe('IgxComboComponent - Signal Forms', () => { @@ -4341,6 +4525,42 @@ export class ComboWithIdComponent { } } + +@Component({ + template: ` + {{ version() }} + + + + `, + imports: [IgxComboComponent], + changeDetection: ChangeDetectionStrategy.OnPush +}) +class IgxComboMutableRecordsComponent { + @ViewChild('combo', { static: true }) + public combo: IgxComboComponent; + + @Input() + public items = [{ id: 1, text: 'One' }, { id: 2, text: 'Two' }]; + + public version = signal(0); + public cancelSelection = false; + public displayText: string | null = null; + + /** Changes a record's key in place. */ + public renameFirstRecord() { + this.items[0].id = 3; + } + + public handleSelectionChanging(args: IComboSelectionChangingEventArgs) { + args.cancel = this.cancelSelection; + if (this.displayText) { + args.displayText = this.displayText; + } + } +} + @Component({ template: ` diff --git a/projects/igniteui-angular/combo/src/combo/combo.component.ts b/projects/igniteui-angular/combo/src/combo/combo.component.ts index 830a3b0e3df..e9ada113472 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.component.ts +++ b/projects/igniteui-angular/combo/src/combo/combo.component.ts @@ -1,18 +1,19 @@ -import { NgClass, NgTemplateOutlet } from '@angular/common'; +import { NgTemplateOutlet } from '@angular/common'; import { AfterViewInit, Component, OnInit, OnDestroy, - ViewChild, Input, Output, EventEmitter, - HostListener, DoCheck, booleanAttribute, ChangeDetectionStrategy, - ViewEncapsulation + ViewEncapsulation, + viewChild, + linkedSignal, + signal } from '@angular/core'; import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; @@ -115,10 +116,14 @@ const diffInSets = (set1: Set, set2: Set): any[] => { { provide: IGX_COMBO_COMPONENT, useExisting: IgxComboComponent }, { provide: NG_VALUE_ACCESSOR, useExisting: IgxComboComponent, multi: true } ], - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '(keydown.ArrowDown)': 'onArrowDown($event)', + '(keydown.Alt.ArrowDown)': 'onArrowDown($event)', + '(keydown.Escape)': 'onEscape($event)' + }, imports: [ NgTemplateOutlet, - NgClass, FormsModule, IgxInputGroupComponent, IgxInputDirective, @@ -143,7 +148,13 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie * When `false`, the combo's list item container will be focused instead */ @Input({ transform: booleanAttribute }) - public autoFocusSearch = true; + public get autoFocusSearch(): boolean { + return this.autoFocusSearchState(); + } + public set autoFocusSearch(value: boolean) { + this.autoFocusSearchState.set(value); + } + private readonly autoFocusSearchState = signal(true); /** * Defines the placeholder value for the combo dropdown search field @@ -161,7 +172,13 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie * ``` */ @Input() - public searchPlaceholder!: string; + public get searchPlaceholder(): string { + return this.searchPlaceholderState(); + } + public set searchPlaceholder(value: string) { + this.searchPlaceholderState.set(value); + } + private readonly searchPlaceholderState = signal(undefined!); /** * Emitted when item selection is changing, before the selection completes @@ -184,8 +201,14 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie public selectionChanged = new EventEmitter(); /** @hidden @internal */ - @ViewChild(IgxComboDropDownComponent, { static: true }) - public dropdown!: IgxComboDropDownComponent; + public get dropdown(): IgxComboDropDownComponent { + return this.dropdownState(); + } + public set dropdown(value: IgxComboDropDownComponent) { + this.dropdownState.set(value); + } + private readonly dropdownQuery = viewChild(IgxComboDropDownComponent); + private readonly dropdownState = linkedSignal(() => this.dropdownQuery() ?? undefined!); /** @hidden @internal */ public get filteredData(): any[] | null { @@ -206,15 +229,12 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie this.comboAPI.register(this); } - @HostListener('keydown.ArrowDown', ['$event']) - @HostListener('keydown.Alt.ArrowDown', ['$event']) public onArrowDown(event: Event) { event.preventDefault(); event.stopPropagation(); this.open(); } - @HostListener('keydown.Escape', ['$event']) public onEscape(event: Event) { event.stopPropagation(); if (this.collapsed) { @@ -247,6 +267,7 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie const selection = Array.isArray(value) ? value.filter(x => x !== undefined) : []; const oldSelection = this.selection; this.selectionService.select_items(this.id, selection, true); + this.selectionRevision.update(revision => revision + 1); this.cdr.markForCheck(); this._displayValue = this.createDisplayText(this.selection, oldSelection); this._value = this.valueKey ? this.selection.map(item => item[this.valueKey]) : this.selection; @@ -258,6 +279,8 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie this._displayValue = this._displayText || this.createDisplayText(this.selection, []); this._value = this.valueKey ? this.selection.map(item => item[this.valueKey]) : this.selection; } + // Check with the host, so records mutated in place still re-render under OnPush. + this.cdr.markForCheck(); } /** @@ -436,6 +459,7 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie this.selectionChanging.emit(args); if (!args.cancel) { this.selectionService.select_items(this.id, args.newValue, true); + this.selectionRevision.update(revision => revision + 1); this._value = args.newValue; if (displayText !== args.displayText) { this._displayValue = this._displayText = args.displayText; diff --git a/projects/igniteui-angular/combo/src/combo/combo.pipes.ts b/projects/igniteui-angular/combo/src/combo/combo.pipes.ts index 9a9b2c62061..a98e902b817 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.pipes.ts +++ b/projects/igniteui-angular/combo/src/combo/combo.pipes.ts @@ -1,4 +1,4 @@ -import { Pipe, PipeTransform, inject } from '@angular/core'; +import { Pipe, PipeTransform, inject, untracked } from '@angular/core'; import { IComboFilteringOptions, IgxComboBase, IGX_COMBO_COMPONENT } from './combo.common'; import { SortingDirection } from 'igniteui-angular/core'; @@ -37,7 +37,8 @@ export class IgxComboGroupingPipe implements PipeTransform { public transform(collection: any[], groupKey: any, valueKey: any, sortingDirection: SortingDirection, compareCollator: Intl.Collator) { // TODO: should filteredData be changed here? - this.combo.filteredData = collection; + // Runs while the template renders, where signal writes are rejected. + untracked(() => this.combo.filteredData = collection); if ((!groupKey && groupKey !== 0) || !collection.length) { return collection; } diff --git a/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts b/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts index 420eb97e2bd..c50f71569e2 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, HostBinding, HostListener, Input, OnDestroy, Output, AfterViewInit, OnInit, booleanAttribute, inject } from '@angular/core'; +import { Directive, ElementRef, EventEmitter, Input, OnDestroy, Output, AfterViewInit, OnInit, booleanAttribute, inject } from '@angular/core'; import { NgModel, FormControlName } from '@angular/forms'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -62,14 +62,30 @@ export interface AutocompleteOverlaySettings { @Directive({ selector: '[igxAutocomplete]', exportAs: 'igxAutocomplete', - standalone: true + host: { + '[attr.autocomplete]': 'autofill', + '[attr.role]': 'role', + '[attr.aria-expanded]': 'ariaExpanded', + '[attr.aria-haspopup]': 'hasPopUp', + '[attr.aria-owns]': 'ariaOwns', + '[attr.aria-activedescendant]': 'ariaActiveDescendant', + '[attr.aria-autocomplete]': 'ariaAutocomplete', + '(input)': 'onInput()', + '(compositionstart)': 'onCompositionStart()', + '(compositionend)': 'onCompositionEnd()', + '(keydown.ArrowDown)': 'onArrowDown($event)', + '(keydown.Alt.ArrowDown)': 'onArrowDown($event)', + '(keydown.ArrowUp)': 'onArrowDown($event)', + '(keydown.Alt.ArrowUp)': 'onArrowDown($event)', + '(keydown.Tab)': 'onTab()', + '(keydown.Shift.Tab)': 'onTab()' + } }) export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective implements OnDestroy, AfterViewInit, OnInit { protected ngModel = inject(NgModel, { self: true, optional: true }); protected formControl = inject(FormControlName, { self: true, optional: true }); protected group = inject(IgxInputGroupComponent, { optional: true }); protected elementRef = inject(ElementRef); - protected cdr = inject(ChangeDetectorRef); /** * Sets the target of the autocomplete directive @@ -116,11 +132,9 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective public autocompleteSettings!: AutocompleteOverlaySettings; /** @hidden @internal */ - @HostBinding('attr.autocomplete') public autofill = 'off'; /** @hidden @internal */ - @HostBinding('attr.role') public role = 'combobox'; /** @@ -173,31 +187,26 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective } /** @hidden @internal */ - @HostBinding('attr.aria-expanded') public get ariaExpanded() { return !this.collapsed; } /** @hidden @internal */ - @HostBinding('attr.aria-haspopup') public get hasPopUp() { return 'listbox'; } /** @hidden @internal */ - @HostBinding('attr.aria-owns') public get ariaOwns() { return this.target.listId; } /** @hidden @internal */ - @HostBinding('attr.aria-activedescendant') public get ariaActiveDescendant() { return !this.target.collapsed && this.target.focusedItem ? this.target.focusedItem.id : null; } /** @hidden @internal */ - @HostBinding('attr.aria-autocomplete') public get ariaAutocomplete() { return 'list'; } @@ -213,13 +222,11 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective private defaultSettings!: OverlaySettings; /** @hidden @internal */ - @HostListener('input') public onInput() { this.open(); } /** @hidden @internal */ - @HostListener('compositionstart') public onCompositionStart(): void { if (!this._composing) { this._composing = true; @@ -227,24 +234,17 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective } /** @hidden @internal */ - @HostListener('compositionend') public onCompositionEnd(): void { this._composing = false; } /** @hidden @internal */ - @HostListener('keydown.ArrowDown', ['$event']) - @HostListener('keydown.Alt.ArrowDown', ['$event']) - @HostListener('keydown.ArrowUp', ['$event']) - @HostListener('keydown.Alt.ArrowUp', ['$event']) public onArrowDown(event: Event) { event.preventDefault(); this.open(); } /** @hidden @internal */ - @HostListener('keydown.Tab') - @HostListener('keydown.Shift.Tab') public onTab() { this.close(); } @@ -378,6 +378,5 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective this.target.focusedItem = null; } this.target.navigateFirst(); - this.cdr.detectChanges(); } } diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts index 824a715e645..4fe7975cfa4 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, HostBinding, booleanAttribute, ChangeDetectionStrategy } from '@angular/core'; +import { Component, Input, booleanAttribute, ChangeDetectionStrategy, signal } from '@angular/core'; let NEXT_ID = 0; /** @@ -11,8 +11,14 @@ let NEXT_ID = 0; `, - changeDetection: ChangeDetectionStrategy.Eager, - standalone: true + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '[attr.aria-labelledby]': 'labelledBy', + '[attr.role]': 'role', + '[attr.aria-disabled]': 'disabled', + '[class.igx-drop-down__group]': 'groupClass', + '[class.igx-drop-down__group--disabled]': 'disabled' + } }) export class IgxDropDownGroupComponent { /** @@ -22,7 +28,6 @@ export class IgxDropDownGroupComponent { return `igx-item-group-label-${this._id}`; } - @HostBinding(`attr.aria-labelledby`) public get labelledBy(): string { return this.labelId; } @@ -30,11 +35,9 @@ export class IgxDropDownGroupComponent { /** * @hidden @internal */ - @HostBinding('attr.role') public role = 'group'; /** @hidden @internal */ - @HostBinding('class.igx-drop-down__group') public groupClass = true; /** * Sets/gets if the item group is disabled @@ -62,9 +65,12 @@ export class IgxDropDownGroupComponent { * **NOTE:** All items inside of a disabled drop down group will be treated as disabled */ @Input({ transform: booleanAttribute }) - @HostBinding(`attr.aria-disabled`) - @HostBinding('class.igx-drop-down__group--disabled') - public disabled = false; + public get disabled(): boolean { + return this._disabled(); + } + public set disabled(value: boolean) { + this._disabled.set(value); + } /** * Sets/gets the label of the item group @@ -88,7 +94,14 @@ export class IgxDropDownGroupComponent { * ``` */ @Input() - public label!: string; + public get label(): string { + return this._label(); + } + public set label(value: string) { + this._label.set(value); + } + private readonly _disabled = signal(false); + private readonly _label = signal(undefined!); private _id = NEXT_ID++; } diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts index 92c7e87f94c..f84ce5422fb 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts @@ -1,5 +1,5 @@ import { IDropDownBase, IGX_DROPDOWN_BASE } from './drop-down.common'; -import { Directive, Input, HostBinding, HostListener, ElementRef, Output, EventEmitter, booleanAttribute, DoCheck, inject } from '@angular/core'; +import { Directive, Input, ElementRef, Output, EventEmitter, booleanAttribute, DoCheck, inject, signal } from '@angular/core'; import { IgxSelectionAPIService } from 'igniteui-angular/core'; import { IgxDropDownGroupComponent } from './drop-down-group.component'; @@ -14,7 +14,20 @@ let NEXT_ID = 0; */ @Directive({ selector: '[igxDropDownItemBase]', - standalone: true + host: { + '[attr.id]': 'id', + '[attr.aria-label]': 'ariaLabel', + '[attr.aria-selected]': 'selected', + '[attr.aria-disabled]': 'disabled', + '[attr.role]': 'role', + '[class.igx-drop-down__item]': 'itemStyle', + '[class.igx-drop-down__item--selected]': 'selected', + '[class.igx-drop-down__item--focused]': 'focused', + '[class.igx-drop-down__header]': 'isHeader', + '[class.igx-drop-down__item--disabled]': 'disabled', + '(click)': 'clicked($event)', + '(mousedown)': 'handleMousedown($event)' + } }) export class IgxDropDownItemBaseDirective implements DoCheck { protected dropDown = inject(IGX_DROPDOWN_BASE); @@ -33,11 +46,14 @@ export class IgxDropDownItemBaseDirective implements DoCheck { * * @memberof IgxSelectItemComponent */ - @HostBinding('attr.id') @Input() - public id = `igx-drop-down-item-${NEXT_ID++}`; + public get id(): string { + return this._idState(); + } + public set id(value: string) { + this._idState.set(value); + } - @HostBinding('attr.aria-label') @Input() public get ariaLabel(): string | null{ return this._label ? this._label : this.value ? this.value : null; @@ -92,12 +108,16 @@ export class IgxDropDownItemBaseDirective implements DoCheck { * ``` */ @Input() - public value: any; + public get value(): any { + return this._valueState(); + } + public set value(value: any) { + this._valueState.set(value); + } /** * @hidden @internal */ - @HostBinding('class.igx-drop-down__item') public get itemStyle(): boolean { return !this.isHeader; } @@ -116,8 +136,6 @@ export class IgxDropDownItemBaseDirective implements DoCheck { * ``` */ @Input({ transform: booleanAttribute }) - @HostBinding('attr.aria-selected') - @HostBinding('class.igx-drop-down__item--selected') public get selected(): boolean { return this._selected; } @@ -143,7 +161,6 @@ export class IgxDropDownItemBaseDirective implements DoCheck { * let isMyItemFocused = mySelectedItem.focused; * ``` */ - @HostBinding('class.igx-drop-down__item--focused') public get focused(): boolean { return this.isSelectable && this._focused; } @@ -179,8 +196,12 @@ export class IgxDropDownItemBaseDirective implements DoCheck { * ``` */ @Input({ transform: booleanAttribute }) - @HostBinding('class.igx-drop-down__header') - public isHeader!: boolean; + public get isHeader(): boolean { + return this._isHeaderState(); + } + public set isHeader(value: boolean) { + this._isHeaderState.set(value); + } /** * Sets/gets if the given item is disabled @@ -201,8 +222,6 @@ export class IgxDropDownItemBaseDirective implements DoCheck { * **NOTE:** Drop-down items inside of a disabled drop down group will always count as disabled */ @Input({ transform: booleanAttribute }) - @HostBinding('attr.aria-disabled') - @HostBinding('class.igx-drop-down__item--disabled') public get disabled(): boolean { return this.group ? this.group.disabled || this._disabled : this._disabled; } @@ -219,8 +238,12 @@ export class IgxDropDownItemBaseDirective implements DoCheck { * ``` */ @Input() - @HostBinding('attr.role') - public role = 'option'; + public get role(): string { + return this._roleState(); + } + public set role(value: string) { + this._roleState.set(value); + } /** * Gets item index @@ -256,24 +279,58 @@ export class IgxDropDownItemBaseDirective implements DoCheck { /** * @hidden */ - protected _focused = false; - protected _selected = false; - protected _index: number | null = null; - protected _disabled = false; - protected _label: string | null = null; + private readonly _focusedState = signal(false); + private readonly _selectedState = signal(false); + private readonly _disabledState = signal(false); + private readonly _valueState = signal(undefined); + + protected get _focused(): boolean { + return this._focusedState(); + } + protected set _focused(value: boolean) { + this._focusedState.set(value); + } + protected get _selected(): boolean { + return this._selectedState(); + } + protected set _selected(value: boolean) { + this._selectedState.set(value); + } + protected get _disabled(): boolean { + return this._disabledState(); + } + protected set _disabled(value: boolean) { + this._disabledState.set(value); + } + private readonly _idState = signal(`igx-drop-down-item-${NEXT_ID++}`); + private readonly _isHeaderState = signal(undefined!); + private readonly _roleState = signal('option'); + private readonly _indexState = signal(null); + private readonly _labelState = signal(null); + + protected get _index(): number | null { + return this._indexState(); + } + protected set _index(value: number | null) { + this._indexState.set(value); + } + protected get _label(): string | null { + return this._labelState(); + } + protected set _label(value: string | null) { + this._labelState.set(value); + } /** * @hidden * @internal */ - @HostListener('click', ['$event']) public clicked(_event: MouseEvent): void { } /** * @hidden * @internal */ - @HostListener('mousedown', ['$event']) public handleMousedown(event: MouseEvent): void { if (!this.dropDown.allowItemsFocus) { event.preventDefault(); diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts index abce94f72c6..dba212f0c5b 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts @@ -1,6 +1,5 @@ import { Component, - HostBinding, ChangeDetectionStrategy } from '@angular/core'; import { IgxDropDownItemBaseDirective } from './drop-down-item.base'; @@ -12,8 +11,10 @@ import { IgxDropDownItemBaseDirective } from './drop-down-item.base'; @Component({ selector: 'igx-drop-down-item', templateUrl: 'drop-down-item.component.html', - changeDetection: ChangeDetectionStrategy.Eager, - standalone: true + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '[attr.tabindex]': 'setTabIndex' + } }) export class IgxDropDownItemComponent extends IgxDropDownItemBaseDirective { /** @@ -26,7 +27,7 @@ export class IgxDropDownItemComponent extends IgxDropDownItemBaseDirective { public override get focused(): boolean { let focusedState = this._focused; if (this.hasIndex) { - const focusedItem = this.selection!.first_item(`${this.dropDown.id}-active`); + const focusedItem = this.dropDown.focusedItem; const focusedIndex = focusedItem ? focusedItem.index : -1; focusedState = this._index === focusedIndex; } @@ -58,7 +59,7 @@ export class IgxDropDownItemComponent extends IgxDropDownItemBaseDirective { */ public override get selected(): boolean { if (this.hasIndex) { - const item = this.selection!.first_item(`${this.dropDown.id}`); + const item = this.dropDown.selectedItem; return item ? item.index === this._index && item.value === this.value : false; } return this._selected; @@ -78,7 +79,6 @@ export class IgxDropDownItemComponent extends IgxDropDownItemBaseDirective { /** * @hidden @internal */ - @HostBinding('attr.tabindex') public get setTabIndex() { const shouldSetTabIndex = this.dropDown.allowItemsFocus && this.isSelectable; if (shouldSetTabIndex) { diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts index 172c4db0163..b037528c493 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts @@ -1,4 +1,4 @@ -import { Directive, Input, HostListener, inject, HostBinding } from '@angular/core'; +import { Directive, Input, inject } from '@angular/core'; import { IGX_DROPDOWN_BASE } from './drop-down.common'; import { IDropDownNavigationDirective } from './drop-down.common'; import { IgxDropDownBaseDirective } from './drop-down.base'; @@ -9,7 +9,10 @@ import { DropDownActionKey } from './drop-down.common'; */ @Directive({ selector: '[igxDropDownItemNavigation]', - standalone: true + host: { + '[attr.aria-activedescendant]': 'activeDescendant', + '(keydown)': 'handleKeyDown($event)' + } }) export class IgxDropDownItemNavigationDirective implements IDropDownNavigationDirective { public dropdown = inject(IGX_DROPDOWN_BASE, { self: true, optional: true }); @@ -53,7 +56,6 @@ export class IgxDropDownItemNavigationDirective implements IDropDownNavigationDi this._target = target ? target : this.dropdown!; } - @HostBinding('attr.aria-activedescendant') public get activeDescendant(): string { return this._target?.activeDescendant!; } @@ -61,7 +63,6 @@ export class IgxDropDownItemNavigationDirective implements IDropDownNavigationDi /** * Captures keydown events and calls the appropriate handlers on the target component */ - @HostListener('keydown', ['$event']) public handleKeyDown(event: KeyboardEvent) { if (event) { const key = event.key.toLowerCase(); diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts index c2f9a78f5c5..86e26ebd340 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts @@ -1,8 +1,9 @@ import { - Input, HostBinding, ElementRef, QueryList, Output, EventEmitter, ChangeDetectorRef, Directive, + Input, ElementRef, QueryList, Output, EventEmitter, ChangeDetectorRef, Directive, OnInit, DOCUMENT, - inject + inject, + signal } from '@angular/core'; import { Navigate, ISelectionEventArgs } from './drop-down.common'; @@ -19,7 +20,12 @@ let NEXT_ID = 0; * Properties and methods for navigating (highlighting/focusing) items from the collection * Properties and methods for selecting items from the collection */ -@Directive() +@Directive({ + host: { + '[attr.id]': 'id', + '[style.maxHeight]': 'maxHeight' + } +}) export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit { protected elementRef = inject(ElementRef); protected cdr = inject(ChangeDetectorRef); @@ -48,7 +54,12 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit * ``` */ @Input() - public width!: string; + public get width(): string { + return this._widthState(); + } + public set width(value: string) { + this._widthState.set(value); + } /** * Gets/Sets the height of the drop down @@ -63,7 +74,12 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit * ``` */ @Input() - public height!: string; + public get height(): string { + return this._heightState(); + } + public set height(value: string) { + this._heightState.set(value); + } /** * Gets/Sets the drop down's id @@ -77,7 +93,6 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit * * ``` */ - @HostBinding('attr.id') @Input() public get id(): string { return this._id; @@ -99,8 +114,12 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit * ``` */ @Input() - @HostBinding('style.maxHeight') - public maxHeight: string = null!; + public get maxHeight(): string { + return this._maxHeightState(); + } + public set maxHeight(value: string) { + this._maxHeightState.set(value); + } /** * Get all non-header items @@ -178,8 +197,24 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit protected _width: any; protected _height: any; - protected _focusedItem: any = null; - protected _id = `igx-drop-down-${NEXT_ID++}`; + private readonly _widthState = signal(undefined!); + private readonly _heightState = signal(undefined!); + private readonly _maxHeightState = signal(null!); + private readonly _focusedItemState = signal(null); + private readonly _idState = signal(`igx-drop-down-${NEXT_ID++}`); + + protected get _focusedItem(): IgxDropDownItemBaseDirective | null { + return this._focusedItemState(); + } + protected set _focusedItem(value: IgxDropDownItemBaseDirective | null) { + this._focusedItemState.set(value); + } + protected get _id(): string { + return this._idState(); + } + protected set _id(value: string) { + this._idState.set(value); + } protected computedStyles: any; /** @@ -239,7 +274,7 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit */ public navigateItem(newIndex: number) { if (newIndex !== -1) { - const oldItem = this._focusedItem; + const oldItem = this.focusedItem; const newItem = this.items[newIndex]; if (oldItem) { oldItem.focused = false; diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.spec.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.spec.ts index a69f9d8c339..16e2da63e57 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.spec.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.spec.ts @@ -1029,6 +1029,91 @@ describe('IgxDropDown ', () => { expect(expectedScroll - acceptableDelta < scrollTop && expectedScroll + acceptableDelta > scrollTop).toBe(true); }); }); + describe('Zoneless state updates', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [NoopAnimationsModule, SignalStateDropDownComponent], + providers: [provideZonelessChangeDetection()] + }).compileComponents(); + fixture = TestBed.createComponent(SignalStateDropDownComponent); + await fixture.whenStable(); + dropdown = fixture.componentInstance.dropdown; + dropdown.open(); + await fixture.whenStable(); + }); + + it('updates the active descendant and focused item after programmatic navigation', async () => { + dropdown.navigateNext(); + await fixture.whenStable(); + + const item = dropdown.items[0].element.nativeElement as HTMLElement; + expect(item.classList.contains(CSS_CLASS_FOCUSED)).toBeTrue(); + expect(fixture.nativeElement.querySelector('input').getAttribute('aria-activedescendant')).toBe(item.id); + + dropdown.navigateNext(); + await fixture.whenStable(); + + expect(item.classList.contains(CSS_CLASS_FOCUSED)).toBeFalse(); + expect(dropdown.items[1].element.nativeElement.classList.contains(CSS_CLASS_FOCUSED)).toBeTrue(); + }); + + it('renders group state and labels changed through their public properties', async () => { + const group = fixture.componentInstance.group as IgxDropDownGroupComponent; + group.disabled = true; + group.label = 'Unavailable'; + await fixture.whenStable(); + + const groupElement = fixture.debugElement.query(By.directive(IgxDropDownGroupComponent)).nativeElement as HTMLElement; + expect(groupElement.getAttribute('aria-disabled')).toBe('true'); + expect(groupElement.querySelector('label').textContent).toBe('Unavailable'); + expect(dropdown.items[0].element.nativeElement.getAttribute('aria-disabled')).toBe('true'); + + group.disabled = false; + await fixture.whenStable(); + expect(dropdown.items[0].element.nativeElement.getAttribute('aria-disabled')).toBe('false'); + }); + + it('renders programmatic selection and clearing without forced change detection', async () => { + dropdown.setSelectedItem(1); + await fixture.whenStable(); + + const item = dropdown.items[1].element.nativeElement as HTMLElement; + expect(item.getAttribute('aria-selected')).toBe('true'); + expect(item.classList.contains(CSS_CLASS_SELECTED)).toBeTrue(); + + dropdown.clearSelection(); + await fixture.whenStable(); + expect(item.getAttribute('aria-selected')).toBe('false'); + }); + + it('renders dimensions changed through the public properties', async () => { + dropdown.width = '320px'; + dropdown.height = '180px'; + dropdown.maxHeight = '200px'; + await fixture.whenStable(); + + expect(dropdown.scrollContainer.style.height).toBe('180px'); + expect(dropdown.scrollContainer.style.maxHeight).toBe('200px'); + expect(dropdown.scrollContainer.parentElement.style.width).toBe('320px'); + }); + + it('renders item attributes changed through their public properties', async () => { + const item = dropdown.items[0]; + const element = item.element.nativeElement as HTMLElement; + + item.id = 'custom-item-id'; + item.ariaLabel = 'Custom label'; + item.role = 'menuitem'; + item.isHeader = true; + await fixture.whenStable(); + + expect(element.id).toBe('custom-item-id'); + expect(element.getAttribute('aria-label')).toBe('Custom label'); + expect(element.getAttribute('role')).toBe('menuitem'); + expect(element.classList.contains('igx-drop-down__header')).toBeTrue(); + }); + }); + describe('Zoneless virtualization tests', () => { let scroll: IgxForOfDirective; beforeEach(async () => { @@ -1220,7 +1305,7 @@ describe('IgxDropDown ', () => { for (let i = 0; i < groupItems.length; i++) { const elemAttr = groupItems[i].attributes; expect(elemAttr['aria-disabled'].value).toEqual('false'); - expect(elemAttr['aria-labelledby'].value).toEqual(`igx-item-group-label-${i}`); + expect(elemAttr['aria-labelledby'].value).toEqual(groupItems[i].querySelector('label').id); expect(elemAttr['role'].value).toEqual(`group`); } groups.first.disabled = true; @@ -1456,6 +1541,27 @@ describe('IgxDropDown ', () => { }); }); +@Component({ + template: ` + + + + First + Second + + + `, + imports: [IgxDropDownComponent, IgxDropDownItemComponent, IgxDropDownGroupComponent, IgxDropDownItemNavigationDirective], + changeDetection: ChangeDetectionStrategy.OnPush +}) +class SignalStateDropDownComponent { + @ViewChild(IgxDropDownComponent, { static: true }) + public dropdown: IgxDropDownComponent; + + @ViewChild(IgxDropDownGroupComponent, { static: true }) + public group: IgxDropDownGroupComponent; +} + @Component({ template: ` diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts index 1502f26de69..485466bcc44 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts @@ -15,6 +15,7 @@ import { SimpleChanges, booleanAttribute, inject, + signal, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; @@ -56,12 +57,24 @@ import { ConnectedPositioningStrategy } from 'igniteui-angular/core'; styleUrl: 'drop-down.component.css', encapsulation: ViewEncapsulation.None, providers: [{ provide: IGX_DROPDOWN_BASE, useExisting: IgxDropDownComponent }], - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, imports: [IgxToggleDirective] }) export class IgxDropDownComponent extends IgxDropDownBaseDirective implements IDropDownBase, OnChanges, AfterViewInit, OnDestroy { protected selection = inject(IgxSelectionAPIService); - protected _activeDescendantId: string | null = null; + private readonly _activeDescendantState = signal(null); + private readonly _allowItemsFocus = signal(false); + private readonly _labelledBy = signal(undefined!); + private readonly _role = signal('listbox'); + /** Lets views react to selection service changes, which are not reactive. */ + protected readonly selectionRevision = signal(0); + + protected get _activeDescendantId(): string | null { + return this._activeDescendantState(); + } + protected set _activeDescendantId(value: string | null) { + this._activeDescendantState.set(value); + } /** * @hidden @@ -129,7 +142,12 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID * ``` */ @Input({ transform: booleanAttribute }) - public allowItemsFocus = false; + public get allowItemsFocus(): boolean { + return this._allowItemsFocus(); + } + public set allowItemsFocus(value: boolean) { + this._allowItemsFocus.set(value); + } /** * Sets aria-labelledby attribute value. @@ -138,7 +156,12 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID * ``` */ @Input() - public labelledBy!: string; + public get labelledBy(): string { + return this._labelledBy(); + } + public set labelledBy(value: string) { + this._labelledBy.set(value); + } /** * Gets/sets the `role` attribute of the drop down. Default is 'listbox'. @@ -148,7 +171,12 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID * ``` */ @Input() - public role = 'listbox'; + public get role(): string { + return this._role(); + } + public set role(value: string) { + this._role.set(value); + } @ContentChild(IgxForOfToken) protected virtDir!: IgxForOfToken; @@ -164,8 +192,9 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID */ public override get focusedItem(): IgxDropDownItemBaseDirective | null { if (this.virtDir) { - return this._focusedItem && this._focusedItem.index !== -1 ? - (this.children.find(e => e.index === this._focusedItem.index) || null) : + const focused = this._focusedItem; + return focused && focused.index !== -1 ? + (this.children.find(e => e.index === focused.index) || null) : null; } return this._focusedItem; @@ -219,6 +248,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID * ``` */ public get selectedItem(): IgxDropDownItemBaseDirective { + this.selectionRevision(); const selectedItem = this.selection.first_item(this.id); if (selectedItem) { return selectedItem; @@ -475,8 +505,9 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID if (this.virtDir) { this.virtDir.igxForItemSize = 28; this.virtDir.chunkLoad.pipe(takeUntil(this.destroy$)).subscribe(() => { - const item = this._focusedItem - ? this.children.find(e => e.index === this._focusedItem.index) + const focused = this._focusedItem; + const item = focused + ? this.children.find(e => e.index === focused.index) : null; this._activeDescendantId = item?.id ?? null; this.cdr.markForCheck(); @@ -571,6 +602,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID if (!args.cancel) { if (this.isSelectionValid(args.newSelection)) { this.selection.set(this.id, new Set([args.newSelection])); + this.selectionRevision.update(revision => revision + 1); if (!this.virtDir) { if (oldSelection) { oldSelection.selected = false; @@ -602,6 +634,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID if (this.selectedItem && !args.cancel) { this.selectedItem.selected = false; this.selection.clear(this.id); + this.selectionRevision.update(revision => revision + 1); } } @@ -622,8 +655,9 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID } protected focusItem(value: boolean) { - if (value || this._focusedItem) { - this._focusedItem.focused = value; + const focused = this._focusedItem; + if (focused) { + focused.focused = value; } } @@ -660,4 +694,3 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID return subRequired; } } - diff --git a/projects/igniteui-angular/select/src/select/select-group.component.ts b/projects/igniteui-angular/select/src/select/select-group.component.ts index ad03feb0f23..f161b9d71c8 100644 --- a/projects/igniteui-angular/select/src/select/select-group.component.ts +++ b/projects/igniteui-angular/select/src/select/select-group.component.ts @@ -11,7 +11,7 @@ import { IgxDropDownGroupComponent } from 'igniteui-angular/drop-down'; `, - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, standalone: true }) export class IgxSelectGroupComponent extends IgxDropDownGroupComponent { diff --git a/projects/igniteui-angular/select/src/select/select-item.component.ts b/projects/igniteui-angular/select/src/select/select-item.component.ts index 42d79e25d9b..86e7b43bfd3 100644 --- a/projects/igniteui-angular/select/src/select/select-item.component.ts +++ b/projects/igniteui-angular/select/src/select/select-item.component.ts @@ -4,12 +4,17 @@ import { IgxDropDownItemComponent } from 'igniteui-angular/drop-down'; @Component({ selector: 'igx-select-item', templateUrl: 'select-item.component.html', - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, standalone: true }) export class IgxSelectItemComponent extends IgxDropDownItemComponent { /** @hidden @internal */ - public override isHeader!: boolean; + public override get isHeader(): boolean { + return super.isHeader; + } + public override set isHeader(value: boolean) { + super.isHeader = value; + } private _text: any; @@ -54,7 +59,7 @@ export class IgxSelectItemComponent extends IgxDropDownItemComponent { * ``` */ public override get selected() { - return !this.isHeader && !this.disabled && this.selection!.is_item_selected(this.dropDown.id, this); + return !this.isHeader && !this.disabled && this.dropDown.selectedItem === this; } public override set selected(value: any) { diff --git a/projects/igniteui-angular/select/src/select/select.component.spec.ts b/projects/igniteui-angular/select/src/select/select.component.spec.ts index 59d123699c3..4f01b63a802 100644 --- a/projects/igniteui-angular/select/src/select/select.component.spec.ts +++ b/projects/igniteui-angular/select/src/select/select.component.spec.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, DebugElement, OnInit, ElementRef, inject, ChangeDetectorRef, DOCUMENT, Injector, ChangeDetectionStrategy, signal } from '@angular/core'; +import { Component, ViewChild, DebugElement, OnInit, ElementRef, inject, ChangeDetectorRef, DOCUMENT, Injector, ChangeDetectionStrategy, signal, provideZonelessChangeDetection } from '@angular/core'; import { NgStyle } from '@angular/common'; import { ComponentFixture, TestBed, tick, fakeAsync, waitForAsync, discardPeriodicTasks } from '@angular/core/testing'; import { FormsModule, UntypedFormGroup, UntypedFormBuilder, UntypedFormControl, Validators, ReactiveFormsModule, NgForm, NgControl } from '@angular/forms'; @@ -2725,6 +2725,64 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); }); }); + + describe('Zoneless state updates', () => { + beforeEach(async () => { + TestBed.resetTestingModule(); + await TestBed.configureTestingModule({ + imports: [NoopAnimationsModule, IgxSelectComponent], + providers: [provideZonelessChangeDetection()] + }).compileComponents(); + fixture = TestBed.createComponent(IgxSelectComponent); + select = fixture.componentInstance; + await fixture.whenStable(); + }); + + afterEach(() => { + fixture.destroy(); + // The select overwrites the host id, so TestBed can't remove it. + fixture.nativeElement.remove(); + }); + + it('should render a disabled state set through the forms API without forced change detection', async () => { + select.setDisabledState(true); + await fixture.whenStable(); + expect(select.getEditElement().disabled).toBeTrue(); + + select.setDisabledState(false); + await fixture.whenStable(); + expect(select.getEditElement().disabled).toBeFalse(); + }); + + it('should render a placeholder changed through its property without forced change detection', async () => { + select.placeholder = 'Pick a city'; + await fixture.whenStable(); + expect(select.getEditElement().getAttribute('placeholder')).toBe('Pick a city'); + }); + }); + + describe('Zoneless item selection', () => { + beforeEach(async () => { + TestBed.resetTestingModule(); + await TestBed.configureTestingModule({ + imports: [NoopAnimationsModule, SignalStateSelectComponent], + providers: [provideZonelessChangeDetection()] + }).compileComponents(); + fixture = TestBed.createComponent(SignalStateSelectComponent); + select = fixture.componentInstance.select; + await fixture.whenStable(); + }); + + it('should render the selected item after a programmatic value change', async () => { + select.value = 'Varna'; + await fixture.whenStable(); + + const [first, second] = select.items.map(item => item.element.nativeElement as HTMLElement); + expect(second.getAttribute('aria-selected')).toBe('true'); + expect(second.classList.contains('igx-drop-down__item--selected')).toBeTrue(); + expect(first.getAttribute('aria-selected')).toBe('false'); + }); + }); }); describe('IgxSelect - Signal Forms', () => { @@ -3296,6 +3354,22 @@ class IgxSelectWithIdComponent { public items: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']; } + +@Component({ + template: ` + + Sofia + Varna + + `, + imports: [IgxSelectComponent, IgxSelectItemComponent], + changeDetection: ChangeDetectionStrategy.OnPush +}) +class SignalStateSelectComponent { + @ViewChild('select', { static: true }) + public select: IgxSelectComponent; +} + @Component({ template: ` diff --git a/projects/igniteui-angular/select/src/select/select.component.ts b/projects/igniteui-angular/select/src/select/select.component.ts index d22f5248aaf..030f5f1a285 100644 --- a/projects/igniteui-angular/select/src/select/select.component.ts +++ b/projects/igniteui-angular/select/src/select/select.component.ts @@ -21,6 +21,7 @@ import { ViewChild, ViewChildren, inject, + signal, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; @@ -95,7 +96,7 @@ export class IgxSelectFooterDirective { ], styleUrls: ['../../../drop-down/src/drop-down/drop-down.component.css', 'select.component.css'], encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, imports: [IgxInputGroupComponent, IgxInputDirective, IgxSelectItemNavigationDirective, IgxSuffixDirective, IgxReadOnlyInputDirective, NgTemplateOutlet, IgxIconComponent, IgxToggleDirective] }) export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelectBase, ControlValueAccessor, @@ -104,6 +105,12 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec private _inputGroupType = inject(IGX_INPUT_GROUP_TYPE, { optional: true }); private _injector = inject(Injector); + constructor() { + super(); + // Default only; a bound maxHeight is applied afterwards. + this.maxHeight = '256px'; + } + /** @hidden @internal */ @ViewChild('inputGroup', { read: IgxInputGroupComponent, static: true }) public inputGroup!: IgxInputGroupComponent; @@ -134,7 +141,13 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec * Sets input placeholder. * */ - @Input() public placeholder!: string; + @Input() + public get placeholder(): string { + return this._placeholder(); + } + public set placeholder(value: string) { + this._placeholder.set(value); + } /** * Disables the component. @@ -142,7 +155,13 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec * * ``` */ - @Input({ transform: booleanAttribute }) public disabled = false; + @Input({ transform: booleanAttribute }) + public get disabled(): boolean { + return this._disabled(); + } + public set disabled(value: boolean) { + this._disabled.set(value); + } /** * Sets custom overlay settings for the select component. @@ -157,8 +176,12 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec public defaultClass = true; /** @hidden @internal */ - @HostBinding('style.maxHeight') - public override maxHeight = '256px'; + public override get maxHeight(): string { + return super.maxHeight; + } + public override set maxHeight(value: string) { + super.maxHeight = value; + } /** * Emitted before the dropdown is opened @@ -219,7 +242,12 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec * ``` */ @ContentChild(IgxSelectToggleIconDirective, { read: TemplateRef }) - public toggleIconTemplate: TemplateRef = null!; + public get toggleIconTemplate(): TemplateRef { + return this._toggleIconTemplate(); + } + public set toggleIconTemplate(value: TemplateRef) { + this._toggleIconTemplate.set(value); + } /** * The custom template, if any, that should be used when rendering the HEADER for the select items list @@ -242,7 +270,12 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec * ``` */ @ContentChild(IgxSelectHeaderDirective, { read: TemplateRef, static: false }) - public headerTemplate: TemplateRef = null!; + public get headerTemplate(): TemplateRef { + return this._headerTemplate(); + } + public set headerTemplate(value: TemplateRef) { + this._headerTemplate.set(value); + } /** * The custom template, if any, that should be used when rendering the FOOTER for the select items list @@ -265,24 +298,49 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec * ``` */ @ContentChild(IgxSelectFooterDirective, { read: TemplateRef, static: false }) - public footerTemplate: TemplateRef = null!; + public get footerTemplate(): TemplateRef { + return this._footerTemplate(); + } + public set footerTemplate(value: TemplateRef) { + this._footerTemplate.set(value); + } @ContentChild(IgxHintDirective, { read: ElementRef }) private hintElement!: ElementRef; /** @hidden @internal */ - public override width!: string; + public override get width(): string { + return super.width; + } + public override set width(value: string) { + super.width = value; + } /** @hidden @internal */ - public override allowItemsFocus = false; + public override get allowItemsFocus(): boolean { + return super.allowItemsFocus; + } + public override set allowItemsFocus(value: boolean) { + super.allowItemsFocus = value; + } /** @hidden @internal */ - public override height!: string; + public override get height(): string { + return super.height; + } + public override set height(value: string) { + super.height = value; + } private ngControl: NgControl = null!; private control: NgControlAdapter | null = null; private _overlayDefaults!: OverlaySettings; - private _value: any; - private _type: IgxInputGroupType | null = null; + private readonly _value = signal(undefined); + private readonly _placeholder = signal(undefined!); + private readonly _disabled = signal(false); + private readonly _type = signal(null); + private readonly _toggleIconTemplate = signal>(null!); + private readonly _headerTemplate = signal>(null!); + private readonly _footerTemplate = signal>(null!); /** * Gets/Sets the component value. @@ -302,13 +360,13 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec */ @Input() public get value(): any { - return this._value; + return this._value(); } public set value(v: any) { - if (this._value === v) { + if (this._value() === v) { return; } - this._value = v; + this._value.set(v); this.setSelection(this.items.find(x => x.value === this.value)!); } @@ -321,11 +379,11 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec */ @Input() public get type(): IgxInputGroupType { - return this._type || this._inputGroupType || 'box'; + return this._type() || this._inputGroupType || 'box'; } public set type(val: IgxInputGroupType) { - this._type = val; + this._type.set(val); } /** @hidden @internal */ @@ -336,6 +394,7 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec /** @hidden @internal */ public override get selectedItem(): IgxSelectItemComponent { + this.selectionRevision(); return this.selection.first_item(this.id); } @@ -391,7 +450,7 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec } this.setSelection(newSelection); - this._value = newSelection.value; + this._value.set(newSelection.value); if (event) { this.toggleDirective.close(); @@ -625,6 +684,7 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec } else { this.selection.clear(this.id); } + this.selectionRevision.update(revision => revision + 1); } } diff --git a/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.spec.ts index e1ff4301ae7..c54c5db3bd9 100644 --- a/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.spec.ts @@ -1,5 +1,5 @@ import { AsyncPipe } from '@angular/common'; -import { AfterViewInit, ChangeDetectorRef, Component, DOCUMENT, DebugElement, ElementRef, Injector, OnDestroy, OnInit, ViewChild, inject, ChangeDetectionStrategy, signal } from '@angular/core'; +import { AfterViewInit, ChangeDetectorRef, Component, DOCUMENT, DebugElement, ElementRef, Injector, OnDestroy, OnInit, ViewChild, inject, ChangeDetectionStrategy, signal, provideZonelessChangeDetection } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { FormControl, FormGroup, FormsModule, NgForm, ReactiveFormsModule, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { FormField, disabled, form as signalForm, required } from '@angular/forms/signals'; @@ -3156,6 +3156,121 @@ describe('IgxSimpleCombo', () => { } }); }); + + describe('Zoneless state updates', () => { + beforeEach(async () => { + TestBed.resetTestingModule(); + await TestBed.configureTestingModule({ + imports: [NoopAnimationsModule, IgxSimpleComboComponent], + providers: [provideZonelessChangeDetection()] + }).compileComponents(); + fixture = TestBed.createComponent(IgxSimpleComboComponent); + fixture.componentRef.setInput('valueKey', 'id'); + fixture.componentRef.setInput('displayKey', 'label'); + fixture.componentRef.setInput('data', [{ id: 1, label: 'First' }, { id: 2, label: 'Second' }]); + combo = fixture.componentInstance; + await fixture.whenStable(); + }); + + afterEach(() => { + fixture.destroy(); + // The combo overwrites the host id, so TestBed can't remove it. + fixture.nativeElement.remove(); + }); + + it('should render programmatic disabled state changes without forced change detection', async () => { + combo.setDisabledState(true); + await fixture.whenStable(); + expect(combo.getEditElement().hasAttribute('disabled')).toBeTrue(); + + combo.setDisabledState(false); + await fixture.whenStable(); + expect(combo.getEditElement().hasAttribute('disabled')).toBeFalse(); + }); + + it('should render a programmatic selection and deselection without forced change detection', async () => { + combo.select(1); + await fixture.whenStable(); + expect((combo.getEditElement() as HTMLInputElement).value).toBe('First'); + expect(fixture.nativeElement.querySelector('.igx-combo__clear-button')).not.toBeNull(); + + combo.deselect(); + await fixture.whenStable(); + expect((combo.getEditElement() as HTMLInputElement).value).toBe(''); + expect(fixture.nativeElement.querySelector('.igx-combo__clear-button')).toBeNull(); + }); + + it('should follow the total item count when detecting remote data', async () => { + // Read before a count arrives, where a cached result used to stick. + expect(combo.isRemote).toBeFalse(); + + combo.totalItemCount = 100; + await fixture.whenStable(); + expect(combo.isRemote).toBeTrue(); + + combo.totalItemCount = 0; + await fixture.whenStable(); + expect(combo.isRemote).toBeFalse(); + }); + }); + + describe('Mutable data reconciliation', () => { + let host: IgxSimpleComboMutableRecordsComponent; + + const rendered = (record: { id: number }) => + combo.dropdown.items.find(item => item.value === record); + const ariaSelected = (record: { id: number }) => + rendered(record).element.nativeElement.getAttribute('aria-selected'); + const renameFirstRecord = () => + (fixture.nativeElement.querySelector('.rename-first') as HTMLButtonElement).click(); + + beforeEach(async () => { + TestBed.resetTestingModule(); + await TestBed.configureTestingModule({ + imports: [NoopAnimationsModule, IgxSimpleComboMutableRecordsComponent], + providers: [provideZonelessChangeDetection()] + }).compileComponents(); + fixture = TestBed.createComponent(IgxSimpleComboMutableRecordsComponent); + host = fixture.componentInstance; + combo = host.combo; + await fixture.whenStable(); + }); + + it('should render a displayed field changed in place once the consumer view is checked', async () => { + const second = host.items[1]; + const renderedText = () => rendered(second).element.nativeElement.textContent.trim(); + combo.open(); + await fixture.whenStable(); + expect(renderedText()).toBe('Two'); + + // Notify through a host signal; a DOM event would close the overlay. + second.text = 'Two changed'; + host.version.update(version => version + 1); + await fixture.whenStable(); + + expect(fixture.nativeElement.querySelector('.host-version').textContent).toBe('1'); + expect(combo.collapsed).toBeFalse(); + expect(renderedText()).toBe('Two changed'); + }); + it('should deselect an item whose record key changes in place', async () => { + const first = host.items[0]; + combo.select(1); + combo.open(); + await fixture.whenStable(); + expect(rendered(first).selected).toBeTrue(); + expect(ariaSelected(first)).toBe('true'); + + renameFirstRecord(); + await fixture.whenStable(); + + expect(first.id).toBe(3); + expect(combo.isItemSelected(1)).toBeTrue(); + expect(combo.isItemSelected(3)).toBeFalse(); + expect(combo.selection).toEqual({ id: 1 }); + expect(rendered(first).selected).toBeFalse(); + expect(ariaSelected(first)).toBe('false'); + }); + }); }); describe('IgxSimpleComboComponent - Signal Forms', () => { @@ -3844,6 +3959,30 @@ export class IgxSimpleComboTabBehaviorTestComponent implements OnInit { } } + +@Component({ + template: ` + {{ version() }} + + + `, + imports: [IgxSimpleComboComponent], + changeDetection: ChangeDetectionStrategy.OnPush +}) +class IgxSimpleComboMutableRecordsComponent { + @ViewChild('combo', { static: true }) + public combo: IgxSimpleComboComponent; + + public version = signal(0); + + public items = [{ id: 1, text: 'One' }, { id: 2, text: 'Two' }]; + + /** Changes a record's key in place. */ + public renameFirstRecord() { + this.items[0].id = 3; + } +} + @Component({ template: ` diff --git a/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.ts b/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.ts index ca683655673..046be7baf53 100644 --- a/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.ts +++ b/projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.ts @@ -1,5 +1,6 @@ import { NgTemplateOutlet } from '@angular/common'; -import { AfterViewInit, Component, DoCheck, EventEmitter, Output, ViewChild, ViewEncapsulation, inject, ChangeDetectionStrategy } from '@angular/core'; +import { AfterViewInit, Component, DoCheck, EventEmitter, Output, ViewEncapsulation, inject, ChangeDetectionStrategy, viewChild, linkedSignal, signal +} from '@angular/core'; import { ControlValueAccessor, FormGroupDirective, NG_VALUE_ACCESSOR } from '@angular/forms'; import { takeUntil } from 'rxjs/operators'; @@ -52,14 +53,14 @@ export interface ISimpleComboSelectionChangingEventArgs extends ISimpleComboSele @Component({ selector: 'igx-simple-combo', templateUrl: 'simple-combo.component.html', - styleUrls: ['../../../combo/src/combo/combo.component.css'], + styleUrl: '../../../combo/src/combo/combo.component.css', providers: [ IgxComboAPIService, { provide: IGX_COMBO_COMPONENT, useExisting: IgxSimpleComboComponent }, { provide: NG_VALUE_ACCESSOR, useExisting: IgxSimpleComboComponent, multi: true } ], encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.Eager, + changeDetection: ChangeDetectionStrategy.OnPush, host: { '(keydown.ArrowDown)': 'onArrowDown($any($event))', '(keydown.Alt.ArrowDown)': 'onArrowDown($any($event))' @@ -71,12 +72,24 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co private formGroupDirective = inject(FormGroupDirective, { optional: true }); /** @hidden @internal */ - @ViewChild(IgxComboDropDownComponent, { static: true }) - public dropdown!: IgxComboDropDownComponent; + public get dropdown(): IgxComboDropDownComponent { + return this.dropdownState(); + } + public set dropdown(value: IgxComboDropDownComponent) { + this.dropdownState.set(value); + } + private readonly dropdownQuery = viewChild(IgxComboDropDownComponent); + private readonly dropdownState = linkedSignal(() => this.dropdownQuery() ?? undefined!); /** @hidden @internal */ - @ViewChild(IgxComboAddItemComponent) - public addItem!: IgxComboAddItemComponent; + public get addItem(): IgxComboAddItemComponent { + return this.addItemState(); + } + public set addItem(value: IgxComboAddItemComponent) { + this.addItemState.set(value); + } + private readonly addItemQuery = viewChild(IgxComboAddItemComponent); + private readonly addItemState = linkedSignal(() => this.addItemQuery() ?? undefined!); /** * Emitted when item selection is changing, before the selection completes @@ -98,8 +111,14 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co @Output() public selectionChanged = new EventEmitter(); - @ViewChild(IgxTextSelectionDirective, { static: true }) - private textSelection!: IgxTextSelectionDirective; + private get textSelection(): IgxTextSelectionDirective { + return this.textSelectionState(); + } + private set textSelection(value: IgxTextSelectionDirective) { + this.textSelectionState.set(value); + } + private readonly textSelectionQuery = viewChild(IgxTextSelectionDirective); + private readonly textSelectionState = linkedSignal(() => this.textSelectionQuery() ?? undefined!); public override get value(): any { return this._value[0]; @@ -118,7 +137,13 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co } /** @hidden @internal */ - public composing = false; + public get composing(): boolean { + return this.composingState(); + } + public set composing(value: boolean) { + this.composingState.set(value); + } + private readonly composingState = signal(false); private _updateInput = true; @@ -147,6 +172,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co } protected get hasSelectedItem(): boolean { + this.selectionRevision(); return !!this.selectionService.get(this.id).size; } @@ -202,6 +228,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co public writeValue(value: any): void { const oldSelection = super.selection; this.selectionService.select_items(this.id, this.isValid(value) ? [value] : [], true); + this.selectionRevision.update(revision => revision + 1); this.cdr.markForCheck(); this._displayValue = this.createDisplayText(super.selection, oldSelection); this._value = this.valueKey ? super.selection.map(item => item[this.valueKey]) : super.selection; @@ -262,6 +289,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co // and sets the selection to an invalid value in writeValue method if (!this.isValid(this.selectedItem)) { this.selectionService.clear(this.id); + this.selectionRevision.update(revision => revision + 1); this._displayValue = ''; } @@ -274,6 +302,8 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co this._displayValue = this.createDisplayText(super.selection, []); this._value = this.valueKey ? super.selection.map(item => item[this.valueKey]) : super.selection; } + // Check with the host, so records mutated in place still re-render under OnPush. + this.cdr.markForCheck(); } /** @hidden @internal */ @@ -303,6 +333,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co this.selectionChanging.emit(args); if (!args.cancel) { this.selectionService.select_items(this.id, [], true); + this.selectionRevision.update(revision => revision + 1); const changedArgs: ISimpleComboSelectionChangedEventArgs = { newValue: undefined, oldValue: this.selectedItem, @@ -537,6 +568,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co : []; argsSelection = Array.isArray(argsSelection) ? argsSelection : [argsSelection]; this.selectionService.select_items(this.id, argsSelection, true); + this.selectionRevision.update(revision => revision + 1); this._value = argsSelection; if (this._updateInput) { this.comboInput.value = this._displayValue = this.searchValue = displayText !== args.displayText diff --git a/src/app/virtualization-compare/data.ts b/src/app/virtualization-compare/data.ts new file mode 100644 index 00000000000..789ff4c7304 --- /dev/null +++ b/src/app/virtualization-compare/data.ts @@ -0,0 +1,13784 @@ +/* eslint-disable */ +export const DATA: any[] = [ + { + ProductID: 1, + ProductName: 'Chai', + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 18.0, + UnitsInStock: 39, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2012-02-12'), + }, + { + ProductID: 2, + ProductName: 'Chang', + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 19.0, + UnitsInStock: 17, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2003-03-17'), + }, + { + ProductID: 3, + ProductName: 'Aniseed Syrup', + SupplierID: 1, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 10.0, + UnitsInStock: 13, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2006-03-17'), + }, + { + ProductID: 4, + ProductName: 'Chef Antons Cajun Seasoning', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '48 - 6 oz jars', + UnitPrice: 22.0, + UnitsInStock: 53, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-03-17'), + }, + { + ProductID: 5, + ProductName: 'Chef Antons Gumbo Mix', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 21.35, + UnitsInStock: 0, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2011-11-11'), + }, + { + ProductID: 6, + ProductName: 'Grandmas Boysenberry Spread', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 25.0, + UnitsInStock: 0, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2017-12-17'), + }, + { + ProductID: 7, + ProductName: 'Uncle Bobs Organic Dried Pears', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 30.0, + UnitsInStock: 150, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2016-07-17'), + }, + { + ProductID: 8, + ProductName: 'Northwoods Cranberry Sauce', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '12 - 12 oz jars', + UnitPrice: 40.0, + UnitsInStock: 6, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-01-17'), + }, + { + ProductID: 9, + ProductName: 'Mishi Kobe Niku', + SupplierID: 4, + CategoryID: 6, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 97.0, + UnitsInStock: 29, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2010-02-17'), + }, + { + ProductID: 10, + ProductName: 'Ikura', + SupplierID: 4, + CategoryID: 8, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 31.0, + UnitsInStock: 31, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-05-17'), + }, + { + ProductID: 11, + ProductName: 'Queso Cabrales', + SupplierID: 5, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 21.0, + UnitsInStock: 22, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2009-01-17'), + }, + { + ProductID: 12, + ProductName: 'Queso Manchego La Pastora', + SupplierID: 5, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 38.0, + UnitsInStock: 86, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-11-17'), + }, + { + ProductID: 13, + ProductName: 'Konbu', + SupplierID: 6, + CategoryID: 8, + QuantityPerUnit: '2 kg box', + UnitPrice: 6.0, + UnitsInStock: 24, + UnitsOnOrder: 30, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2015-03-17'), + }, + { + ProductID: 14, + ProductName: 'Tofu', + SupplierID: 6, + CategoryID: 7, + QuantityPerUnit: '40 - 100 g pkgs.', + UnitPrice: 23.25, + UnitsInStock: 35, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-06-17'), + }, + { + ProductID: 15, + ProductName: 'Genen Shouyu', + SupplierID: 6, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 15.5, + UnitsInStock: 39, + UnitsOnOrder: 30, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2014-03-17'), + }, + { + ProductID: 16, + ProductName: 'Pavlova', + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 17.45, + UnitsInStock: 29, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2018-03-28'), + }, + { + ProductID: 17, + ProductName: 'Alice Mutton', + SupplierID: 7, + CategoryID: 6, + QuantityPerUnit: '20 - 1 kg tins', + UnitPrice: 39.0, + UnitsInStock: 0, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2015-08-17'), + }, + { + ProductID: 18, + ProductName: 'Carnarvon Tigers', + SupplierID: 7, + CategoryID: 8, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 62.5, + UnitsInStock: 42, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-09-27'), + }, + { + ProductID: 19, + ProductName: 'Teatime Chocolate Biscuits', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '', + UnitPrice: 9.2, + UnitsInStock: 25, + UnitsOnOrder: 30, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2001-03-17'), + }, + { + ProductID: 20, + ProductName: 'Sir Rodneys Marmalade', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: undefined, + UnitPrice: 4.5, + UnitsInStock: 40, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-03-17'), + }, + { + ProductID: 21, + ProductName: 'Sir Rodneys Scones', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '24 pkgs. x 4 pieces', + UnitPrice: 10.0, + UnitsInStock: 3, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2003-05-14'), + }, + { + ProductID: 22, + ProductName: 'Gustafs Knäckebröd', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '24 - 500 g pkgs.', + UnitPrice: 21.0, + UnitsInStock: 104, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2007-11-02'), + }, + { + ProductID: 23, + ProductName: 'Tunnbröd', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '12 - 250 g pkgs.', + UnitPrice: 9.0, + UnitsInStock: 61, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2010-01-23'), + }, + { + ProductID: 24, + ProductName: 'Guaraná Fantástica', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 4.5, + UnitsInStock: 20, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2013-07-08'), + }, + { + ProductID: 25, + ProductName: 'NuNuCa Nuß-Nougat-Creme', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '20 - 450 g glasses', + UnitPrice: 14.0, + UnitsInStock: 76, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-09-19'), + }, + { + ProductID: 26, + ProductName: 'Gumbär Gummibärchen', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '100 - 250 g bags', + UnitPrice: 31.23, + UnitsInStock: 15, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-02-27'), + }, + { + ProductID: 27, + ProductName: 'Schoggi Schokolade', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '100 - 100 g pieces', + UnitPrice: 43.9, + UnitsInStock: 49, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2002-12-05'), + }, + { + ProductID: 28, + ProductName: 'Rössle Sauerkraut', + SupplierID: 12, + CategoryID: 7, + QuantityPerUnit: '25 - 825 g cans', + UnitPrice: 45.6, + UnitsInStock: 26, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2011-06-11'), + }, + { + ProductID: 29, + ProductName: 'Thüringer Rostbratwurst', + SupplierID: 12, + CategoryID: 6, + QuantityPerUnit: '50 bags x 30 sausgs.', + UnitPrice: 123.79, + UnitsInStock: 0, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2008-04-30'), + }, + { + ProductID: 30, + ProductName: 'Nord-Ost Matjeshering', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '10 - 200 g glasses', + UnitPrice: 25.89, + UnitsInStock: 10, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-08-21'), + }, + { + ProductID: 31, + ProductName: 'Gorgonzola Telino', + SupplierID: 14, + CategoryID: 4, + QuantityPerUnit: '12 - 100 g pkgs', + UnitPrice: 12.5, + UnitsInStock: 0, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2006-10-09'), + }, + { + ProductID: 32, + ProductName: 'Mascarpone Fabioli', + SupplierID: 14, + CategoryID: 4, + QuantityPerUnit: '24 - 200 g pkgs.', + UnitPrice: 32.0, + UnitsInStock: 9, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-01-16'), + }, + { + ProductID: 33, + ProductName: 'Geitost', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '500 g', + UnitPrice: 2.5, + UnitsInStock: 112, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2015-03-03'), + }, + { + ProductID: 34, + ProductName: 'Sasquatch Ale', + SupplierID: 16, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 14.0, + UnitsInStock: 111, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2009-07-26'), + }, + { + ProductID: 35, + ProductName: 'Steeleye Stout', + SupplierID: 16, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 18.0, + UnitsInStock: 20, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2012-11-18'), + }, + { + ProductID: 36, + ProductName: 'Inlagd Sill', + SupplierID: 17, + CategoryID: 8, + QuantityPerUnit: '24 - 250 g jars', + UnitPrice: 19.0, + UnitsInStock: 112, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2005-05-07'), + }, + { + ProductID: 37, + ProductName: 'Gravad lax', + SupplierID: 17, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 26.0, + UnitsInStock: 11, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2017-01-29'), + }, + { + ProductID: 38, + ProductName: 'Côte de Blaye', + SupplierID: 18, + CategoryID: 1, + QuantityPerUnit: '12 - 75 cl bottles', + UnitPrice: 263.5, + UnitsInStock: 17, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2003-09-12'), + }, + { + ProductID: 39, + ProductName: 'Chartreuse verte', + SupplierID: 18, + CategoryID: 1, + QuantityPerUnit: '750 cc per bottle', + UnitPrice: 18.0, + UnitsInStock: 69, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2010-04-04'), + }, + { + ProductID: 40, + ProductName: 'Boston Crab Meat', + SupplierID: 19, + CategoryID: 8, + QuantityPerUnit: '24 - 4 oz tins', + UnitPrice: 18.4, + UnitsInStock: 123, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-06-22'), + }, + { + ProductID: 41, + ProductName: 'Jacks New England Clam Chowder', + SupplierID: 19, + CategoryID: 8, + QuantityPerUnit: '12 - 12 oz cans', + UnitPrice: 9.65, + UnitsInStock: 85, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2016-10-13'), + }, + { + ProductID: 42, + ProductName: 'Singaporean Hokkien Fried Mee', + SupplierID: 20, + CategoryID: 5, + QuantityPerUnit: '32 - 1 kg pkgs.', + UnitPrice: 14.0, + UnitsInStock: 26, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2002-02-08'), + }, + { + ProductID: 43, + ProductName: 'Ipoh Coffee', + SupplierID: 20, + CategoryID: 1, + QuantityPerUnit: '16 - 500 g tins', + UnitPrice: 46.0, + UnitsInStock: 17, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-12-01'), + }, + { + ProductID: 44, + ProductName: 'Gula Malacca', + SupplierID: 20, + CategoryID: 2, + QuantityPerUnit: '20 - 2 kg bags', + UnitPrice: 19.45, + UnitsInStock: 27, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2007-08-15'), + }, + { + ProductID: 45, + ProductName: 'Rogede sild', + SupplierID: 21, + CategoryID: 8, + QuantityPerUnit: '1k pkg.', + UnitPrice: 9.5, + UnitsInStock: 5, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2011-03-25'), + }, + { + ProductID: 46, + ProductName: 'Spegesild', + SupplierID: 21, + CategoryID: 8, + QuantityPerUnit: '4 - 450 g glasses', + UnitPrice: 12.0, + UnitsInStock: 95, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-10-31'), + }, + { + ProductID: 47, + ProductName: 'Zaanse koeken', + SupplierID: 22, + CategoryID: 3, + QuantityPerUnit: '10 - 4 oz boxes', + UnitPrice: 9.5, + UnitsInStock: 36, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2014-05-18'), + }, + { + ProductID: 48, + ProductName: 'Chocolade', + SupplierID: 22, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 12.75, + UnitsInStock: 15, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2009-09-06'), + }, + { + ProductID: 49, + ProductName: 'Maxilaku', + SupplierID: 23, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 20.0, + UnitsInStock: 10, + UnitsOnOrder: 60, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2006-01-11'), + }, + { + ProductID: 50, + ProductName: 'Valkoinen suklaa', + SupplierID: 23, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 16.25, + UnitsInStock: 65, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-02-19'), + }, + { + ProductID: 51, + ProductName: 'Manjimup Dried Apples', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '50 - 300 g pkgs.', + UnitPrice: 53.0, + UnitsInStock: 20, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2005-07-14'), + }, + { + ProductID: 52, + ProductName: 'Filo Mix', + SupplierID: 24, + CategoryID: 5, + QuantityPerUnit: '16 - 2 kg boxes', + UnitPrice: 7.0, + UnitsInStock: 38, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2012-04-27'), + }, + { + ProductID: 53, + ProductName: 'Perth Pasties', + SupplierID: 24, + CategoryID: 6, + QuantityPerUnit: '48 pieces', + UnitPrice: 32.8, + UnitsInStock: 0, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2001-11-09'), + }, + { + ProductID: 54, + ProductName: 'Tourtière', + SupplierID: 25, + CategoryID: 6, + QuantityPerUnit: '16 pies', + UnitPrice: 7.45, + UnitsInStock: 21, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-06-30'), + }, + { + ProductID: 55, + ProductName: 'Pâté chinois', + SupplierID: 25, + CategoryID: 6, + QuantityPerUnit: '24 boxes x 2 pies', + UnitPrice: 24.0, + UnitsInStock: 115, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2008-08-24'), + }, + { + ProductID: 56, + ProductName: 'Gnocchi di nonna Alice', + SupplierID: 26, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 38.0, + UnitsInStock: 21, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2017-10-05'), + }, + { + ProductID: 57, + ProductName: 'Ravioli Angelo', + SupplierID: 26, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 19.5, + UnitsInStock: 36, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2004-03-21'), + }, + { + ProductID: 58, + ProductName: 'Escargots de Bourgogne', + SupplierID: 27, + CategoryID: 8, + QuantityPerUnit: '24 pieces', + UnitPrice: 13.25, + UnitsInStock: 62, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-01-07'), + }, + { + ProductID: 59, + ProductName: 'Raclette Courdavault', + SupplierID: 28, + CategoryID: 4, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 55.0, + UnitsInStock: 79, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-12-16'), + }, + { + ProductID: 60, + ProductName: 'Camembert Pierrot', + SupplierID: 28, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g rounds', + UnitPrice: 34.0, + UnitsInStock: 19, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2003-02-25'), + }, + { + ProductID: 61, + ProductName: 'Bergen Apple Juice Extra', + SupplierID: 7, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 98.95, + UnitsInStock: 71, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2013-02-14'), + }, + { + ProductID: 62, + ProductName: 'Escargot Quinoa Deluxe', + SupplierID: 22, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 51.25, + UnitsInStock: 67, + UnitsOnOrder: 20, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2013-02-22'), + }, + { + ProductID: 63, + ProductName: 'Bavarian Barbecue Sauce Gold', + SupplierID: 10, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 161.25, + UnitsInStock: 61, + UnitsOnOrder: 30, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2002-06-17'), + }, + { + ProductID: 64, + ProductName: 'Cascade Parmesan Shavings Traditional', + SupplierID: 3, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 86.5, + UnitsInStock: 140, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2002-09-22'), + }, + { + ProductID: 65, + ProductName: 'Aberdeen Chili Sauce Selection', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 232.5, + UnitsInStock: 115, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2001-02-08'), + }, + { + ProductID: 66, + ProductName: 'Athens Trout Fillets', + SupplierID: 15, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 240.25, + UnitsInStock: 29, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2003-05-05'), + }, + { + ProductID: 67, + ProductName: 'Valencia Trout Fillets Reserve', + SupplierID: 23, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 165.95, + UnitsInStock: 124, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2015-04-18'), + }, + { + ProductID: 68, + ProductName: 'Nordsee Polenta Selection', + SupplierID: 4, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 62.25, + UnitsInStock: 45, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-06-19'), + }, + { + ProductID: 69, + ProductName: 'Tokyo Caviar Classic', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 175.5, + UnitsInStock: 89, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2011-02-17'), + }, + { + ProductID: 70, + ProductName: 'Tokyo Red Peppers Classic', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 170.0, + UnitsInStock: 85, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-02-21'), + }, + { + ProductID: 71, + ProductName: 'Valencia Lemonade Deluxe', + SupplierID: 20, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 81.99, + UnitsInStock: 68, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2017-11-18'), + }, + { + ProductID: 72, + ProductName: 'Santiago Tuna Steaks Extra', + SupplierID: 27, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 119.75, + UnitsInStock: 45, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-04-13'), + }, + { + ProductID: 73, + ProductName: 'Lima Manchego Selection', + SupplierID: 20, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 232.75, + UnitsInStock: 35, + UnitsOnOrder: 15, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2010-01-28'), + }, + { + ProductID: 74, + ProductName: 'Santiago Apple Juice Extra', + SupplierID: 13, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 50.99, + UnitsInStock: 63, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2005-02-09'), + }, + { + ProductID: 75, + ProductName: 'Louisiana Granola Reserve', + SupplierID: 15, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 12.99, + UnitsInStock: 122, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2013-05-26'), + }, + { + ProductID: 76, + ProductName: 'Bordeaux Avocados Gold', + SupplierID: 14, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 157.75, + UnitsInStock: 51, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2020-09-21'), + }, + { + ProductID: 77, + ProductName: 'Ghent Horseradish', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 120.99, + UnitsInStock: 52, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-04-09'), + }, + { + ProductID: 78, + ProductName: 'Bombay Quinoa Reserve', + SupplierID: 24, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 49.25, + UnitsInStock: 129, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-04-14'), + }, + { + ProductID: 79, + ProductName: 'Odessa Dried Apples Extra', + SupplierID: 26, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 83.0, + UnitsInStock: 23, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2017-01-02'), + }, + { + ProductID: 80, + ProductName: 'Tokyo Gouda Premium', + SupplierID: 22, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 116.25, + UnitsInStock: 15, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-04-25'), + }, + { + ProductID: 81, + ProductName: 'Tallinn Crab Meat Selection', + SupplierID: 11, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 37.5, + UnitsInStock: 149, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2003-03-18'), + }, + { + ProductID: 82, + ProductName: 'Porto Emmental Selection', + SupplierID: 27, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 240.75, + UnitsInStock: 26, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-09-09'), + }, + { + ProductID: 83, + ProductName: 'Naples Ale', + SupplierID: 12, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 66.25, + UnitsInStock: 31, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-12-27'), + }, + { + ProductID: 84, + ProductName: 'Grandma Kellys Granola Extra', + SupplierID: 25, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 196.95, + UnitsInStock: 111, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-03-19'), + }, + { + ProductID: 85, + ProductName: 'Cairo Granola Deluxe', + SupplierID: 27, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 69.99, + UnitsInStock: 90, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2008-08-09'), + }, + { + ProductID: 86, + ProductName: 'Grandma Kellys Honey Cakes Selection', + SupplierID: 2, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 191.0, + UnitsInStock: 62, + UnitsOnOrder: 30, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2013-06-16'), + }, + { + ProductID: 87, + ProductName: 'Santiago Pesto Extra', + SupplierID: 9, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 160.99, + UnitsInStock: 83, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-01-21'), + }, + { + ProductID: 88, + ProductName: 'Uncle Bobs Anchovies', + SupplierID: 22, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 148.75, + UnitsInStock: 123, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2006-08-10'), + }, + { + ProductID: 89, + ProductName: 'Cascade Rye Bread Mix', + SupplierID: 26, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 115.25, + UnitsInStock: 21, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2008-07-20'), + }, + { + ProductID: 90, + ProductName: 'Escargot Chili Sauce Reserve', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 230.5, + UnitsInStock: 31, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-07-17'), + }, + { + ProductID: 91, + ProductName: 'Copenhagen Sardines Traditional', + SupplierID: 8, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 204.75, + UnitsInStock: 72, + UnitsOnOrder: 50, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2020-03-21'), + }, + { + ProductID: 92, + ProductName: 'Aberdeen Bacon Strips Deluxe', + SupplierID: 11, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 154.99, + UnitsInStock: 85, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2012-12-05'), + }, + { + ProductID: 93, + ProductName: 'Vienna Rice Crackers', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 193.5, + UnitsInStock: 13, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2011-11-11'), + }, + { + ProductID: 94, + ProductName: 'Kyoto Harissa Deluxe', + SupplierID: 12, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 30.0, + UnitsInStock: 137, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2000-03-26'), + }, + { + ProductID: 95, + ProductName: 'Escargot Toffee Classic', + SupplierID: 16, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 80.0, + UnitsInStock: 144, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-02-04'), + }, + { + ProductID: 96, + ProductName: 'Bombay Baby Carrots Reserve', + SupplierID: 19, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 132.95, + UnitsInStock: 92, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-05-24'), + }, + { + ProductID: 97, + ProductName: 'Salzburg Espresso Blend Gold', + SupplierID: 20, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 224.75, + UnitsInStock: 76, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2017-04-19'), + }, + { + ProductID: 98, + ProductName: 'Grandma Kellys Marzipan Premium', + SupplierID: 24, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 174.99, + UnitsInStock: 98, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-10-10'), + }, + { + ProductID: 99, + ProductName: 'Chef Antons Couscous Classic', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 200.25, + UnitsInStock: 138, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-05-12'), + }, + { + ProductID: 100, + ProductName: 'Bavarian Iced Tea Original', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 172.75, + UnitsInStock: 33, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-12-23'), + }, + { + ProductID: 101, + ProductName: 'Naples Cornmeal Gold', + SupplierID: 24, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 66.95, + UnitsInStock: 99, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2010-03-23'), + }, + { + ProductID: 102, + ProductName: 'Nordsee King Prawns Classic', + SupplierID: 9, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 5.75, + UnitsInStock: 96, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2007-01-23'), + }, + { + ProductID: 103, + ProductName: 'Riga Quinoa Traditional', + SupplierID: 12, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 22.99, + UnitsInStock: 13, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2009-02-09'), + }, + { + ProductID: 104, + ProductName: 'Highland Mackerel Selection', + SupplierID: 9, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 233.5, + UnitsInStock: 34, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2008-05-28'), + }, + { + ProductID: 105, + ProductName: 'Porto Dried Figs Classic', + SupplierID: 15, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 155.25, + UnitsInStock: 16, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-05-19'), + }, + { + ProductID: 106, + ProductName: 'Helsinki Sea Bass Classic', + SupplierID: 19, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 187.75, + UnitsInStock: 73, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2006-10-25'), + }, + { + ProductID: 107, + ProductName: 'Ghent Fudge Squares Selection', + SupplierID: 26, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 101.0, + UnitsInStock: 55, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2005-09-06'), + }, + { + ProductID: 108, + ProductName: 'Nordsee Muesli Premium', + SupplierID: 17, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 26.99, + UnitsInStock: 62, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-03-25'), + }, + { + ProductID: 109, + ProductName: 'Bordeaux Cider', + SupplierID: 18, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 96.0, + UnitsInStock: 13, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2004-12-28'), + }, + { + ProductID: 110, + ProductName: 'Bombay Clams Traditional', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 240.5, + UnitsInStock: 11, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-02-02'), + }, + { + ProductID: 111, + ProductName: 'Zurich Manchego Selection', + SupplierID: 17, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 4.25, + UnitsInStock: 15, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2008-03-04'), + }, + { + ProductID: 112, + ProductName: 'Andalusia Baby Carrots', + SupplierID: 16, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 226.0, + UnitsInStock: 10, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2013-01-10'), + }, + { + ProductID: 113, + ProductName: 'Kyoto Creme Fraiche Reserve', + SupplierID: 1, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 8.0, + UnitsInStock: 114, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2007-05-26'), + }, + { + ProductID: 114, + ProductName: 'Ravenna Baby Spinach Reserve', + SupplierID: 13, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 74.75, + UnitsInStock: 122, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2003-12-14'), + }, + { + ProductID: 115, + ProductName: 'Provence King Prawns Traditional', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 124.5, + UnitsInStock: 60, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2000-07-21'), + }, + { + ProductID: 116, + ProductName: 'Cairo Lemonade Classic', + SupplierID: 9, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 32.95, + UnitsInStock: 36, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2004-12-18'), + }, + { + ProductID: 117, + ProductName: 'Pavlova Praline Mix Traditional', + SupplierID: 1, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 198.5, + UnitsInStock: 142, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2011-12-23'), + }, + { + ProductID: 118, + ProductName: 'Tokyo Polenta Gold', + SupplierID: 22, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 240.75, + UnitsInStock: 104, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2008-10-11'), + }, + { + ProductID: 119, + ProductName: 'Cairo Lamb Chops Original', + SupplierID: 13, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 114.95, + UnitsInStock: 20, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2017-08-16'), + }, + { + ProductID: 120, + ProductName: 'Toscana Peanut Sauce Classic', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 168.95, + UnitsInStock: 97, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-01-25'), + }, + { + ProductID: 121, + ProductName: 'Gustafs Smoked Salmon Classic', + SupplierID: 5, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 147.0, + UnitsInStock: 24, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2010-08-15'), + }, + { + ProductID: 122, + ProductName: 'Naples Ginger Root Premium', + SupplierID: 17, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 127.5, + UnitsInStock: 42, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2007-05-13'), + }, + { + ProductID: 123, + ProductName: 'Bergen Chicken Breast Gold', + SupplierID: 16, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 40.99, + UnitsInStock: 125, + UnitsOnOrder: 25, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2019-08-28'), + }, + { + ProductID: 124, + ProductName: 'Bergen Roasted Chestnuts Original', + SupplierID: 21, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 161.25, + UnitsInStock: 105, + UnitsOnOrder: 30, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2013-03-10'), + }, + { + ProductID: 125, + ProductName: 'Louisiana Ale Extra', + SupplierID: 26, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 231.0, + UnitsInStock: 1, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2007-10-01'), + }, + { + ProductID: 126, + ProductName: 'Tokyo Gingerbread Original', + SupplierID: 19, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 101.25, + UnitsInStock: 130, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2014-06-22'), + }, + { + ProductID: 127, + ProductName: 'Ghent Egg Noodles Original', + SupplierID: 18, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 206.95, + UnitsInStock: 56, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2012-11-14'), + }, + { + ProductID: 128, + ProductName: 'Alpen Chardonnay', + SupplierID: 22, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 31.5, + UnitsInStock: 5, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-06-19'), + }, + { + ProductID: 129, + ProductName: 'Vienna Semolina Gold', + SupplierID: 7, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 208.75, + UnitsInStock: 107, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-04-17'), + }, + { + ProductID: 130, + ProductName: 'Ghent Fudge Squares Classic', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 86.75, + UnitsInStock: 129, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-01-26'), + }, + { + ProductID: 131, + ProductName: 'Bordeaux Cola Original', + SupplierID: 3, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 200.99, + UnitsInStock: 22, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-04-28'), + }, + { + ProductID: 132, + ProductName: 'Lisbon Pate Selection', + SupplierID: 27, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 144.75, + UnitsInStock: 130, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2017-12-15'), + }, + { + ProductID: 133, + ProductName: 'Porto Blue Cheese Reserve', + SupplierID: 27, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 78.5, + UnitsInStock: 140, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2020-02-11'), + }, + { + ProductID: 134, + ProductName: 'Zurich Gouda Original', + SupplierID: 12, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 30.95, + UnitsInStock: 73, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2003-09-18'), + }, + { + ProductID: 135, + ProductName: 'Aberdeen Shrimp Mix Gold', + SupplierID: 4, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 173.95, + UnitsInStock: 96, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2014-06-21'), + }, + { + ProductID: 136, + ProductName: 'Krakow Chardonnay Selection', + SupplierID: 7, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 88.0, + UnitsInStock: 118, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2012-05-27'), + }, + { + ProductID: 137, + ProductName: 'Ghent Mint Creams Extra', + SupplierID: 5, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 110.95, + UnitsInStock: 73, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-08-17'), + }, + { + ProductID: 138, + ProductName: 'Shanghai Praline Mix Extra', + SupplierID: 2, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 166.75, + UnitsInStock: 0, + UnitsOnOrder: 100, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2003-05-17'), + }, + { + ProductID: 139, + ProductName: 'Naples Kombucha Reserve', + SupplierID: 2, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 130.75, + UnitsInStock: 134, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2004-11-24'), + }, + { + ProductID: 140, + ProductName: 'Lima Red Peppers Gold', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 199.25, + UnitsInStock: 33, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-12-16'), + }, + { + ProductID: 141, + ProductName: 'Louisiana Oat Flakes Selection', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 224.25, + UnitsInStock: 70, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2000-04-27'), + }, + { + ProductID: 142, + ProductName: 'Ravenna Feta Original', + SupplierID: 7, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 240.99, + UnitsInStock: 84, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2005-01-26'), + }, + { + ProductID: 143, + ProductName: 'Ravenna Ketchup Deluxe', + SupplierID: 10, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 114.5, + UnitsInStock: 147, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-04-27'), + }, + { + ProductID: 144, + ProductName: 'Gustafs Ketchup Selection', + SupplierID: 19, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 15.75, + UnitsInStock: 138, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2018-12-12'), + }, + { + ProductID: 145, + ProductName: 'Istanbul Creme Fraiche Reserve', + SupplierID: 24, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 68.25, + UnitsInStock: 26, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-12-05'), + }, + { + ProductID: 146, + ProductName: 'Chef Antons King Prawns Deluxe', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 98.99, + UnitsInStock: 126, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2015-08-19'), + }, + { + ProductID: 147, + ProductName: 'Escargot Baby Carrots Selection', + SupplierID: 7, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 154.95, + UnitsInStock: 52, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2010-03-14'), + }, + { + ProductID: 148, + ProductName: 'Athens Scallops Selection', + SupplierID: 4, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 134.99, + UnitsInStock: 69, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2012-12-27'), + }, + { + ProductID: 149, + ProductName: 'Dublin Stout Classic', + SupplierID: 9, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 116.75, + UnitsInStock: 118, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2018-07-17'), + }, + { + ProductID: 150, + ProductName: 'Bavarian Spelt Flour Original', + SupplierID: 5, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 217.95, + UnitsInStock: 57, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2015-08-15'), + }, + { + ProductID: 151, + ProductName: 'Oslo Portobello Mushrooms Traditional', + SupplierID: 25, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 91.75, + UnitsInStock: 94, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2000-08-22'), + }, + { + ProductID: 152, + ProductName: 'Toscana Lager Selection', + SupplierID: 27, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 32.99, + UnitsInStock: 90, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2008-02-04'), + }, + { + ProductID: 153, + ProductName: 'Valencia Coconut Bars Premium', + SupplierID: 15, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 65.95, + UnitsInStock: 123, + UnitsOnOrder: 100, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2004-01-18'), + }, + { + ProductID: 154, + ProductName: 'Pavlova Truffle Oil Classic', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 93.5, + UnitsInStock: 115, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2008-07-28'), + }, + { + ProductID: 155, + ProductName: 'Highland Smoked Ham Reserve', + SupplierID: 25, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 240.95, + UnitsInStock: 117, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2016-11-09'), + }, + { + ProductID: 156, + ProductName: 'Odessa Avocados Extra', + SupplierID: 23, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 159.95, + UnitsInStock: 147, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2005-12-20'), + }, + { + ProductID: 157, + ProductName: 'Bordeaux Red Peppers Classic', + SupplierID: 27, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 147.95, + UnitsInStock: 10, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-12-28'), + }, + { + ProductID: 158, + ProductName: 'Copenhagen Manchego', + SupplierID: 23, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 12.0, + UnitsInStock: 45, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-04-02'), + }, + { + ProductID: 159, + ProductName: 'Copenhagen Dried Apples Gold', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 100.75, + UnitsInStock: 138, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2019-12-13'), + }, + { + ProductID: 160, + ProductName: 'Toscana Ginger Root', + SupplierID: 27, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 79.95, + UnitsInStock: 118, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-10-22'), + }, + { + ProductID: 161, + ProductName: 'Salzburg Quinoa Premium', + SupplierID: 16, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 188.75, + UnitsInStock: 142, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-11-07'), + }, + { + ProductID: 162, + ProductName: 'Oslo Halloumi Deluxe', + SupplierID: 5, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 93.99, + UnitsInStock: 128, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2020-10-15'), + }, + { + ProductID: 163, + ProductName: 'Copenhagen Pilsner Gold', + SupplierID: 17, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 178.99, + UnitsInStock: 73, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2013-03-06'), + }, + { + ProductID: 164, + ProductName: 'Odessa Horseradish', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 143.95, + UnitsInStock: 150, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2009-06-28'), + }, + { + ProductID: 165, + ProductName: 'Andalusia Artichoke Hearts Reserve', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 40.0, + UnitsInStock: 83, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2001-12-13'), + }, + { + ProductID: 166, + ProductName: 'Sicilian Kombucha Original', + SupplierID: 28, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 161.99, + UnitsInStock: 12, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2019-06-26'), + }, + { + ProductID: 167, + ProductName: 'Tallinn Squid Rings Traditional', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 175.25, + UnitsInStock: 125, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2020-02-22'), + }, + { + ProductID: 168, + ProductName: 'Malaga Sweet Corn Original', + SupplierID: 20, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 99.25, + UnitsInStock: 125, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2001-08-05'), + }, + { + ProductID: 169, + ProductName: 'Aberdeen Fruit Gums Premium', + SupplierID: 13, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 202.5, + UnitsInStock: 149, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-01-08'), + }, + { + ProductID: 170, + ProductName: 'Valencia Artichoke Hearts Deluxe', + SupplierID: 21, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 53.0, + UnitsInStock: 150, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2014-06-19'), + }, + { + ProductID: 171, + ProductName: 'Salzburg Couscous Classic', + SupplierID: 28, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 88.95, + UnitsInStock: 29, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2014-04-21'), + }, + { + ProductID: 172, + ProductName: 'Valencia Pearl Barley Extra', + SupplierID: 7, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 81.95, + UnitsInStock: 12, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2018-08-03'), + }, + { + ProductID: 173, + ProductName: 'Odessa Asparagus Spears Premium', + SupplierID: 4, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 224.25, + UnitsInStock: 81, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2004-05-02'), + }, + { + ProductID: 174, + ProductName: 'Toscana Asparagus Spears Gold', + SupplierID: 2, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 7.0, + UnitsInStock: 128, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2020-03-13'), + }, + { + ProductID: 175, + ProductName: 'Oslo Cherry Tomatoes Traditional', + SupplierID: 21, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 176.25, + UnitsInStock: 35, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-12-16'), + }, + { + ProductID: 176, + ProductName: 'Verona Baby Spinach Reserve', + SupplierID: 5, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 211.25, + UnitsInStock: 119, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2004-09-06'), + }, + { + ProductID: 177, + ProductName: 'Ravenna Lemons Selection', + SupplierID: 26, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 134.25, + UnitsInStock: 137, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2016-01-09'), + }, + { + ProductID: 178, + ProductName: 'Gustafs Cabernet Selection', + SupplierID: 19, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 138.0, + UnitsInStock: 3, + UnitsOnOrder: 60, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2000-11-07'), + }, + { + ProductID: 179, + ProductName: 'Valencia Lamb Chops Premium', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 4.5, + UnitsInStock: 131, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2000-10-19'), + }, + { + ProductID: 180, + ProductName: 'Alpen Squid Rings', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 86.5, + UnitsInStock: 92, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-05-08'), + }, + { + ProductID: 181, + ProductName: 'Bavarian Trout Fillets Original', + SupplierID: 11, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 130.75, + UnitsInStock: 64, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2003-06-26'), + }, + { + ProductID: 182, + ProductName: 'Pavlova Green Tea Deluxe', + SupplierID: 15, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 164.0, + UnitsInStock: 3, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2002-08-13'), + }, + { + ProductID: 183, + ProductName: 'Tokyo Granola Selection', + SupplierID: 20, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 125.25, + UnitsInStock: 137, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-01-19'), + }, + { + ProductID: 184, + ProductName: 'Vienna King Prawns Gold', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 202.5, + UnitsInStock: 1, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-08-14'), + }, + { + ProductID: 185, + ProductName: 'Bergen Almond Biscotti Gold', + SupplierID: 9, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 207.75, + UnitsInStock: 105, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2015-10-04'), + }, + { + ProductID: 186, + ProductName: 'Bombay Pesto Extra', + SupplierID: 5, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 95.0, + UnitsInStock: 16, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2020-04-14'), + }, + { + ProductID: 187, + ProductName: 'Kyoto Harissa Premium', + SupplierID: 5, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 199.95, + UnitsInStock: 139, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-12-26'), + }, + { + ProductID: 188, + ProductName: 'Aberdeen Bulgur Deluxe', + SupplierID: 11, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 101.5, + UnitsInStock: 46, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-09-21'), + }, + { + ProductID: 189, + ProductName: 'Oslo Duck Confit Premium', + SupplierID: 19, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 223.99, + UnitsInStock: 14, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2009-02-06'), + }, + { + ProductID: 190, + ProductName: 'Grandma Kellys Cocoa Drink Reserve', + SupplierID: 9, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 16.75, + UnitsInStock: 9, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2014-02-06'), + }, + { + ProductID: 191, + ProductName: 'Shanghai Salsa Verde Traditional', + SupplierID: 28, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 187.0, + UnitsInStock: 55, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2016-10-08'), + }, + { + ProductID: 192, + ProductName: 'Riga Toffee Selection', + SupplierID: 28, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 141.95, + UnitsInStock: 43, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-01-16'), + }, + { + ProductID: 193, + ProductName: 'Highland Chai Blend Deluxe', + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 54.75, + UnitsInStock: 0, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2011-08-03'), + }, + { + ProductID: 194, + ProductName: 'Gustafs Quark Gold', + SupplierID: 17, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 100.5, + UnitsInStock: 139, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2010-08-12'), + }, + { + ProductID: 195, + ProductName: 'Copenhagen Portobello Mushrooms Gold', + SupplierID: 21, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 96.25, + UnitsInStock: 46, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-01-12'), + }, + { + ProductID: 196, + ProductName: 'Nordsee Lager Original', + SupplierID: 3, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 21.0, + UnitsInStock: 57, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-10-05'), + }, + { + ProductID: 197, + ProductName: 'Dublin Yoghurt Extra', + SupplierID: 14, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 131.5, + UnitsInStock: 89, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2002-02-25'), + }, + { + ProductID: 198, + ProductName: 'Naples Basmati Rice Traditional', + SupplierID: 11, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 83.5, + UnitsInStock: 101, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2019-03-18'), + }, + { + ProductID: 199, + ProductName: 'Sicilian Black Pudding Reserve', + SupplierID: 12, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 140.0, + UnitsInStock: 68, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2001-06-27'), + }, + { + ProductID: 200, + ProductName: 'Cascade Ketchup Premium', + SupplierID: 12, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 116.0, + UnitsInStock: 42, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-03-01'), + }, + { + ProductID: 201, + ProductName: 'Ravenna Balsamic Vinegar Premium', + SupplierID: 13, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 155.0, + UnitsInStock: 30, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-08-24'), + }, + { + ProductID: 202, + ProductName: 'Copenhagen Marshmallows Gold', + SupplierID: 20, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 107.25, + UnitsInStock: 45, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-03-13'), + }, + { + ProductID: 203, + ProductName: 'Andalusia Sardines Gold', + SupplierID: 4, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 43.95, + UnitsInStock: 7, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2011-03-24'), + }, + { + ProductID: 204, + ProductName: 'Kyoto Soy Sauce Reserve', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 12.95, + UnitsInStock: 53, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2016-12-02'), + }, + { + ProductID: 205, + ProductName: 'Athens Sardines Premium', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 167.0, + UnitsInStock: 51, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2014-01-06'), + }, + { + ProductID: 206, + ProductName: 'Cascade Mozzarella Reserve', + SupplierID: 1, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 224.5, + UnitsInStock: 131, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2004-08-08'), + }, + { + ProductID: 207, + ProductName: 'Naples Duck Confit Premium', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 229.95, + UnitsInStock: 27, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2013-05-25'), + }, + { + ProductID: 208, + ProductName: 'Salzburg Parmesan Shavings Traditional', + SupplierID: 24, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 5.25, + UnitsInStock: 45, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2010-02-01'), + }, + { + ProductID: 209, + ProductName: 'Ghent Apple Juice Traditional', + SupplierID: 26, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 204.99, + UnitsInStock: 9, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-07-16'), + }, + { + ProductID: 210, + ProductName: 'Dublin Cola Traditional', + SupplierID: 4, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 6.0, + UnitsInStock: 70, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-04-17'), + }, + { + ProductID: 211, + ProductName: 'Bordeaux Caviar Traditional', + SupplierID: 27, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 195.95, + UnitsInStock: 105, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2004-07-22'), + }, + { + ProductID: 212, + ProductName: 'Alpen Beef Jerky Selection', + SupplierID: 10, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 44.5, + UnitsInStock: 72, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2012-07-11'), + }, + { + ProductID: 213, + ProductName: 'Oslo Camembert Original', + SupplierID: 14, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 106.95, + UnitsInStock: 11, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2010-08-13'), + }, + { + ProductID: 214, + ProductName: 'Helsinki Pesto Deluxe', + SupplierID: 18, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 59.25, + UnitsInStock: 39, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-02-04'), + }, + { + ProductID: 215, + ProductName: 'Nordsee Cajun Rub Classic', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 19.5, + UnitsInStock: 8, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-07-04'), + }, + { + ProductID: 216, + ProductName: 'Istanbul Green Tea Traditional', + SupplierID: 21, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 33.95, + UnitsInStock: 11, + UnitsOnOrder: 15, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2003-12-05'), + }, + { + ProductID: 217, + ProductName: 'Istanbul Dried Apples Reserve', + SupplierID: 16, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 207.0, + UnitsInStock: 108, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-03-06'), + }, + { + ProductID: 218, + ProductName: 'Krakow Pilsner Classic', + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 146.95, + UnitsInStock: 69, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-08-14'), + }, + { + ProductID: 219, + ProductName: 'Louisiana Chili Sauce Premium', + SupplierID: 4, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 215.25, + UnitsInStock: 41, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-12-20'), + }, + { + ProductID: 220, + ProductName: 'Krakow Soy Sauce Traditional', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 97.5, + UnitsInStock: 21, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2005-11-17'), + }, + { + ProductID: 221, + ProductName: 'Bombay Scallops Classic', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 120.95, + UnitsInStock: 93, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2020-02-10'), + }, + { + ProductID: 222, + ProductName: 'Cairo Penne Original', + SupplierID: 1, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 172.25, + UnitsInStock: 108, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-02-20'), + }, + { + ProductID: 223, + ProductName: 'Seville Spelt Flour Deluxe', + SupplierID: 27, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 83.5, + UnitsInStock: 3, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-05-14'), + }, + { + ProductID: 224, + ProductName: 'Cascade Mustard Original', + SupplierID: 7, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 158.5, + UnitsInStock: 125, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2014-05-12'), + }, + { + ProductID: 225, + ProductName: 'Cairo Ginger Root Gold', + SupplierID: 22, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 186.99, + UnitsInStock: 92, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2019-06-01'), + }, + { + ProductID: 226, + ProductName: 'Uncle Bobs Oysters Gold', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 111.0, + UnitsInStock: 76, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-07-20'), + }, + { + ProductID: 227, + ProductName: 'Seville Marshmallows Classic', + SupplierID: 16, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 209.95, + UnitsInStock: 42, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-11-12'), + }, + { + ProductID: 228, + ProductName: 'Tokyo Portobello Mushrooms Reserve', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 95.99, + UnitsInStock: 141, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-06-04'), + }, + { + ProductID: 229, + ProductName: 'Sicilian Ginger Beer Selection', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 199.95, + UnitsInStock: 123, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-09-09'), + }, + { + ProductID: 230, + ProductName: 'Provence Pilsner Classic', + SupplierID: 27, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 103.99, + UnitsInStock: 143, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2007-11-23'), + }, + { + ProductID: 231, + ProductName: 'Utrecht Lager Original', + SupplierID: 11, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 7.25, + UnitsInStock: 59, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-05-19'), + }, + { + ProductID: 232, + ProductName: 'Ravenna Wasabi Paste Extra', + SupplierID: 18, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 45.5, + UnitsInStock: 1, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2017-03-11'), + }, + { + ProductID: 233, + ProductName: 'Gustafs Oat Flakes Selection', + SupplierID: 19, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 207.99, + UnitsInStock: 143, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2010-07-20'), + }, + { + ProductID: 234, + ProductName: 'Nordsee Olive Oil Traditional', + SupplierID: 7, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 101.0, + UnitsInStock: 13, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-01-21'), + }, + { + ProductID: 235, + ProductName: 'Cairo Salami Original', + SupplierID: 20, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 25.0, + UnitsInStock: 51, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2012-11-24'), + }, + { + ProductID: 236, + ProductName: 'Cascade Pesto Extra', + SupplierID: 1, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 226.75, + UnitsInStock: 119, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2012-04-16'), + }, + { + ProductID: 237, + ProductName: 'Zurich Cabernet Gold', + SupplierID: 21, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 127.5, + UnitsInStock: 142, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2012-04-14'), + }, + { + ProductID: 238, + ProductName: 'Santiago Macaroons Premium', + SupplierID: 17, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 11.25, + UnitsInStock: 129, + UnitsOnOrder: 10, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2018-04-01'), + }, + { + ProductID: 239, + ProductName: 'Alpen Pomegranates Original', + SupplierID: 10, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 88.95, + UnitsInStock: 12, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2017-03-10'), + }, + { + ProductID: 240, + ProductName: 'Uncle Bobs Trout Fillets Deluxe', + SupplierID: 12, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 231.5, + UnitsInStock: 95, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-08-08'), + }, + { + ProductID: 241, + ProductName: 'Cascade Mixed Olives Premium', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 114.95, + UnitsInStock: 64, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2016-12-23'), + }, + { + ProductID: 242, + ProductName: 'Verona Soy Sauce Traditional', + SupplierID: 4, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 85.75, + UnitsInStock: 71, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2007-09-09'), + }, + { + ProductID: 243, + ProductName: 'Uncle Bobs Octopus Gold', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 228.0, + UnitsInStock: 52, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-03-03'), + }, + { + ProductID: 244, + ProductName: 'Istanbul Mustard Extra', + SupplierID: 28, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 231.99, + UnitsInStock: 53, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-03-11'), + }, + { + ProductID: 245, + ProductName: 'Vienna Duck Confit Extra', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 145.99, + UnitsInStock: 46, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-05-08'), + }, + { + ProductID: 246, + ProductName: 'Naples Macaroons Classic', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 53.95, + UnitsInStock: 46, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2000-07-04'), + }, + { + ProductID: 247, + ProductName: 'Pavlova Duck Confit Classic', + SupplierID: 9, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 86.25, + UnitsInStock: 55, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2002-01-17'), + }, + { + ProductID: 248, + ProductName: 'Chef Antons Cod Fillets Traditional', + SupplierID: 22, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 23.95, + UnitsInStock: 97, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2001-12-22'), + }, + { + ProductID: 249, + ProductName: 'Dublin Blue Cheese Extra', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 12.95, + UnitsInStock: 150, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2002-03-25'), + }, + { + ProductID: 250, + ProductName: 'Salzburg Meatballs Original', + SupplierID: 17, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 92.75, + UnitsInStock: 129, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2002-06-26'), + }, + { + ProductID: 251, + ProductName: 'Provence Truffle Oil Extra', + SupplierID: 26, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 54.95, + UnitsInStock: 95, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2007-05-13'), + }, + { + ProductID: 252, + ProductName: 'Krakow Sea Bass Selection', + SupplierID: 18, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 105.95, + UnitsInStock: 72, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2011-06-10'), + }, + { + ProductID: 253, + ProductName: 'Vienna Sponge Cake Selection', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 18.95, + UnitsInStock: 141, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2012-01-14'), + }, + { + ProductID: 254, + ProductName: 'Chef Antons Cola Extra', + SupplierID: 14, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 70.99, + UnitsInStock: 91, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-09-08'), + }, + { + ProductID: 255, + ProductName: 'Provence Red Peppers Original', + SupplierID: 28, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 32.0, + UnitsInStock: 32, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2015-05-15'), + }, + { + ProductID: 256, + ProductName: 'Porto Mozzarella Original', + SupplierID: 22, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 203.99, + UnitsInStock: 144, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2014-05-15'), + }, + { + ProductID: 257, + ProductName: 'Cairo Cod Fillets Premium', + SupplierID: 6, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 57.75, + UnitsInStock: 108, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2014-11-20'), + }, + { + ProductID: 258, + ProductName: 'Athens Pate Traditional', + SupplierID: 6, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 21.75, + UnitsInStock: 113, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2005-12-10'), + }, + { + ProductID: 259, + ProductName: 'Krakow Espresso Blend Deluxe', + SupplierID: 11, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 190.25, + UnitsInStock: 67, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2007-10-03'), + }, + { + ProductID: 260, + ProductName: 'Bergen Pearl Barley Original', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 106.95, + UnitsInStock: 16, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2000-07-04'), + }, + { + ProductID: 261, + ProductName: 'Copenhagen Wasabi Paste Classic', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 235.99, + UnitsInStock: 73, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2008-07-27'), + }, + { + ProductID: 262, + ProductName: 'Malaga Sourdough Mix Gold', + SupplierID: 13, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 92.75, + UnitsInStock: 33, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2017-01-10'), + }, + { + ProductID: 263, + ProductName: 'Oslo Roasted Chestnuts Extra', + SupplierID: 15, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 93.5, + UnitsInStock: 43, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2011-02-15'), + }, + { + ProductID: 264, + ProductName: 'Helsinki Meatballs Gold', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 107.75, + UnitsInStock: 96, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-10-23'), + }, + { + ProductID: 265, + ProductName: 'Valencia Oysters Gold', + SupplierID: 7, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 103.0, + UnitsInStock: 100, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2003-12-24'), + }, + { + ProductID: 266, + ProductName: 'Tokyo Polenta Original', + SupplierID: 20, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 126.95, + UnitsInStock: 101, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2015-01-23'), + }, + { + ProductID: 267, + ProductName: 'Istanbul Honey Cakes', + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 14.95, + UnitsInStock: 146, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-02-15'), + }, + { + ProductID: 268, + ProductName: 'Valencia Trout Fillets Selection', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 106.95, + UnitsInStock: 63, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-06-07'), + }, + { + ProductID: 269, + ProductName: 'Escargot Lager Gold', + SupplierID: 4, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 111.5, + UnitsInStock: 66, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2020-04-28'), + }, + { + ProductID: 270, + ProductName: 'Pavlova Fudge Squares Traditional', + SupplierID: 9, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 13.0, + UnitsInStock: 83, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2013-06-04'), + }, + { + ProductID: 271, + ProductName: 'Krakow Portobello Mushrooms Premium', + SupplierID: 25, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 114.75, + UnitsInStock: 113, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2003-10-08'), + }, + { + ProductID: 272, + ProductName: 'Alpen Creme Fraiche Premium', + SupplierID: 21, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 233.25, + UnitsInStock: 30, + UnitsOnOrder: 10, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2014-07-27'), + }, + { + ProductID: 273, + ProductName: 'Ghent Yoghurt Original', + SupplierID: 10, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 193.0, + UnitsInStock: 48, + UnitsOnOrder: 30, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2000-04-04'), + }, + { + ProductID: 274, + ProductName: 'Bordeaux Apple Juice Gold', + SupplierID: 18, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 74.99, + UnitsInStock: 63, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-07-13'), + }, + { + ProductID: 275, + ProductName: 'Naples Asparagus Spears Reserve', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 215.99, + UnitsInStock: 16, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-02-14'), + }, + { + ProductID: 276, + ProductName: 'Louisiana Licorice Drops Original', + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 45.5, + UnitsInStock: 51, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-08-11'), + }, + { + ProductID: 277, + ProductName: 'Naples Mint Creams', + SupplierID: 23, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 238.95, + UnitsInStock: 91, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-08-23'), + }, + { + ProductID: 278, + ProductName: 'Tallinn Sourdough Mix Premium', + SupplierID: 24, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 200.25, + UnitsInStock: 53, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-05-28'), + }, + { + ProductID: 279, + ProductName: 'Chef Antons Mixed Olives', + SupplierID: 16, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 97.95, + UnitsInStock: 3, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2010-09-08'), + }, + { + ProductID: 280, + ProductName: 'Uncle Bobs Sea Bass Deluxe', + SupplierID: 21, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 154.0, + UnitsInStock: 135, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2005-03-08'), + }, + { + ProductID: 281, + ProductName: 'Zurich Praline Mix Extra', + SupplierID: 2, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 120.75, + UnitsInStock: 25, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2014-10-01'), + }, + { + ProductID: 282, + ProductName: 'Grandma Kellys Lemons Gold', + SupplierID: 19, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 153.99, + UnitsInStock: 22, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-03-26'), + }, + { + ProductID: 283, + ProductName: 'Lima Turkey Roast', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 222.99, + UnitsInStock: 134, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-01-05'), + }, + { + ProductID: 284, + ProductName: 'Krakow Cola Deluxe', + SupplierID: 6, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 145.5, + UnitsInStock: 145, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2016-12-28'), + }, + { + ProductID: 285, + ProductName: 'Bavarian Salami Premium', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 67.99, + UnitsInStock: 15, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2009-02-27'), + }, + { + ProductID: 286, + ProductName: 'Tallinn Stout Gold', + SupplierID: 5, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 196.25, + UnitsInStock: 65, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2010-11-10'), + }, + { + ProductID: 287, + ProductName: 'Kyoto Mixed Olives Classic', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 98.99, + UnitsInStock: 9, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2000-03-20'), + }, + { + ProductID: 288, + ProductName: 'Kyoto Green Tea', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 42.99, + UnitsInStock: 102, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2016-07-06'), + }, + { + ProductID: 289, + ProductName: 'Bordeaux Truffle Oil Reserve', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 31.75, + UnitsInStock: 44, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-11-08'), + }, + { + ProductID: 290, + ProductName: 'Zurich Polenta Deluxe', + SupplierID: 7, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 169.25, + UnitsInStock: 8, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2009-01-06'), + }, + { + ProductID: 291, + ProductName: 'Tallinn Clams Premium', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 56.95, + UnitsInStock: 48, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-11-25'), + }, + { + ProductID: 292, + ProductName: 'Cairo Peanut Sauce Traditional', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 10.5, + UnitsInStock: 133, + UnitsOnOrder: 10, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2011-03-11'), + }, + { + ProductID: 293, + ProductName: 'Bavarian Butter Selection', + SupplierID: 9, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 79.5, + UnitsInStock: 97, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-02-27'), + }, + { + ProductID: 294, + ProductName: 'Odessa Bacon Strips Premium', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 66.5, + UnitsInStock: 99, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-02-26'), + }, + { + ProductID: 295, + ProductName: 'Alpen Marshmallows Premium', + SupplierID: 3, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 188.75, + UnitsInStock: 96, + UnitsOnOrder: 20, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2006-03-04'), + }, + { + ProductID: 296, + ProductName: 'Alpen Pearl Barley Selection', + SupplierID: 15, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 211.99, + UnitsInStock: 7, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-06-15'), + }, + { + ProductID: 297, + ProductName: 'Bavarian Chai Blend Selection', + SupplierID: 6, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 212.75, + UnitsInStock: 21, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2018-11-26'), + }, + { + ProductID: 298, + ProductName: 'Alpen Sweet Corn', + SupplierID: 12, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 206.0, + UnitsInStock: 65, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2015-08-10'), + }, + { + ProductID: 299, + ProductName: 'Tokyo Nougat Bars', + SupplierID: 28, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 228.99, + UnitsInStock: 82, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2010-04-12'), + }, + { + ProductID: 300, + ProductName: 'Marrakesh Shrimp Mix Deluxe', + SupplierID: 15, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 59.25, + UnitsInStock: 102, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2019-05-09'), + }, + { + ProductID: 301, + ProductName: 'Grandma Kellys Chai Blend Classic', + SupplierID: 16, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 179.0, + UnitsInStock: 46, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2004-03-15'), + }, + { + ProductID: 302, + ProductName: 'Istanbul Penne Deluxe', + SupplierID: 5, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 96.75, + UnitsInStock: 109, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-12-02'), + }, + { + ProductID: 303, + ProductName: 'Bergen Bulgur Extra', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 15.95, + UnitsInStock: 116, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2013-11-22'), + }, + { + ProductID: 304, + ProductName: 'Oslo Trout Fillets Reserve', + SupplierID: 26, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 91.95, + UnitsInStock: 20, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2002-09-13'), + }, + { + ProductID: 305, + ProductName: 'Tallinn Rye Bread Mix Gold', + SupplierID: 25, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 18.5, + UnitsInStock: 1, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2009-03-18'), + }, + { + ProductID: 306, + ProductName: 'Pavlova Caviar Extra', + SupplierID: 17, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 89.25, + UnitsInStock: 135, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2003-09-21'), + }, + { + ProductID: 307, + ProductName: 'Alpen Caramel Wafers Classic', + SupplierID: 28, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 110.99, + UnitsInStock: 132, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-08-14'), + }, + { + ProductID: 308, + ProductName: 'Alpen Crab Meat Extra', + SupplierID: 22, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 46.25, + UnitsInStock: 12, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2001-12-17'), + }, + { + ProductID: 309, + ProductName: 'Provence Pearl Barley', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 234.99, + UnitsInStock: 110, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2008-07-04'), + }, + { + ProductID: 310, + ProductName: 'Gustafs Quinoa Reserve', + SupplierID: 4, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 12.25, + UnitsInStock: 69, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-05-13'), + }, + { + ProductID: 311, + ProductName: 'Naples Quinoa Premium', + SupplierID: 23, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 7.0, + UnitsInStock: 43, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2012-05-19'), + }, + { + ProductID: 312, + ProductName: 'Shanghai Blue Mussels Reserve', + SupplierID: 12, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 52.99, + UnitsInStock: 140, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2003-10-14'), + }, + { + ProductID: 313, + ProductName: 'Highland Buckwheat Original', + SupplierID: 18, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 135.99, + UnitsInStock: 7, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2011-07-13'), + }, + { + ProductID: 314, + ProductName: 'Shanghai Bratwurst Premium', + SupplierID: 6, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 104.99, + UnitsInStock: 139, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-11-25'), + }, + { + ProductID: 315, + ProductName: 'Lima Smoked Salmon Traditional', + SupplierID: 27, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 101.75, + UnitsInStock: 49, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-01-01'), + }, + { + ProductID: 316, + ProductName: 'Louisiana Sardines Reserve', + SupplierID: 24, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 40.99, + UnitsInStock: 77, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2001-10-28'), + }, + { + ProductID: 317, + ProductName: 'Bordeaux Cola Classic', + SupplierID: 5, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 136.0, + UnitsInStock: 80, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2014-04-22'), + }, + { + ProductID: 318, + ProductName: 'Louisiana Ricotta Gold', + SupplierID: 27, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 178.95, + UnitsInStock: 109, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-02-17'), + }, + { + ProductID: 319, + ProductName: 'Vienna Ginger Root', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 92.25, + UnitsInStock: 100, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2002-09-20'), + }, + { + ProductID: 320, + ProductName: 'Bombay Camembert Reserve', + SupplierID: 16, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 162.5, + UnitsInStock: 86, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2000-03-16'), + }, + { + ProductID: 321, + ProductName: 'Bavarian Blue Mussels Traditional', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 30.25, + UnitsInStock: 65, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2014-06-07'), + }, + { + ProductID: 322, + ProductName: 'Porto Tuna Steaks Original', + SupplierID: 21, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 31.5, + UnitsInStock: 127, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2012-07-06'), + }, + { + ProductID: 323, + ProductName: 'Tokyo Mackerel Classic', + SupplierID: 15, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 123.95, + UnitsInStock: 130, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2011-08-08'), + }, + { + ProductID: 324, + ProductName: 'Escargot Penne Premium', + SupplierID: 1, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 188.25, + UnitsInStock: 150, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2009-05-10'), + }, + { + ProductID: 325, + ProductName: 'Chef Antons Mustard Premium', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 217.25, + UnitsInStock: 8, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2012-01-28'), + }, + { + ProductID: 326, + ProductName: 'Highland Rib Roast Classic', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 203.25, + UnitsInStock: 114, + UnitsOnOrder: 50, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2018-01-05'), + }, + { + ProductID: 327, + ProductName: 'Gustafs Portobello Mushrooms Traditional', + SupplierID: 1, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 169.95, + UnitsInStock: 43, + UnitsOnOrder: 30, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-06-26'), + }, + { + ProductID: 328, + ProductName: 'Santiago Fruit Gums Gold', + SupplierID: 3, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 65.95, + UnitsInStock: 8, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-05-23'), + }, + { + ProductID: 329, + ProductName: 'Cascade Chocolate Truffles Selection', + SupplierID: 1, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 238.95, + UnitsInStock: 50, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-06-07'), + }, + { + ProductID: 330, + ProductName: 'Ghent Spelt Flour Original', + SupplierID: 5, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 192.75, + UnitsInStock: 74, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-06-19'), + }, + { + ProductID: 331, + ProductName: 'Sicilian Dried Apples Deluxe', + SupplierID: 5, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 10.0, + UnitsInStock: 5, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2020-07-28'), + }, + { + ProductID: 332, + ProductName: 'Shanghai Cherry Tomatoes', + SupplierID: 5, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 190.5, + UnitsInStock: 149, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-09-06'), + }, + { + ProductID: 333, + ProductName: 'Cairo Lemons Reserve', + SupplierID: 15, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 155.95, + UnitsInStock: 119, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2020-04-24'), + }, + { + ProductID: 334, + ProductName: 'Aberdeen Cola Deluxe', + SupplierID: 27, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 64.95, + UnitsInStock: 10, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2011-11-01'), + }, + { + ProductID: 335, + ProductName: 'Cascade Mayonnaise Extra', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 198.0, + UnitsInStock: 68, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2001-03-18'), + }, + { + ProductID: 336, + ProductName: 'Riga Clams Reserve', + SupplierID: 24, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 62.75, + UnitsInStock: 23, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-01-21'), + }, + { + ProductID: 337, + ProductName: 'Cairo Trout Fillets Reserve', + SupplierID: 15, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 155.0, + UnitsInStock: 27, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2002-08-07'), + }, + { + ProductID: 338, + ProductName: 'Helsinki Sardines', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 36.0, + UnitsInStock: 35, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2003-12-18'), + }, + { + ProductID: 339, + ProductName: 'Cascade Avocados Premium', + SupplierID: 25, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 140.75, + UnitsInStock: 97, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-06-26'), + }, + { + ProductID: 340, + ProductName: 'Shanghai Pate Selection', + SupplierID: 18, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 84.95, + UnitsInStock: 119, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2013-03-05'), + }, + { + ProductID: 341, + ProductName: 'Porto Kombucha Extra', + SupplierID: 27, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 236.95, + UnitsInStock: 34, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2005-09-26'), + }, + { + ProductID: 342, + ProductName: 'Alpen Oysters', + SupplierID: 3, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 19.0, + UnitsInStock: 68, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-05-07'), + }, + { + ProductID: 343, + ProductName: 'Alpen Horseradish Reserve', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 77.75, + UnitsInStock: 85, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-07-28'), + }, + { + ProductID: 344, + ProductName: 'Tallinn Curry Paste Gold', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 97.75, + UnitsInStock: 48, + UnitsOnOrder: 50, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2003-09-08'), + }, + { + ProductID: 345, + ProductName: 'Cairo Goose Liver Classic', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 11.0, + UnitsInStock: 107, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2004-05-05'), + }, + { + ProductID: 346, + ProductName: 'Bergen Coconut Bars Reserve', + SupplierID: 28, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 240.95, + UnitsInStock: 19, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-04-12'), + }, + { + ProductID: 347, + ProductName: 'Utrecht Barbecue Sauce Original', + SupplierID: 27, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 87.5, + UnitsInStock: 128, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2008-10-04'), + }, + { + ProductID: 348, + ProductName: 'Seville Chardonnay Deluxe', + SupplierID: 8, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 72.75, + UnitsInStock: 148, + UnitsOnOrder: 30, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-01-13'), + }, + { + ProductID: 349, + ProductName: 'Lima Coconut Bars Traditional', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 28.25, + UnitsInStock: 100, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2000-12-19'), + }, + { + ProductID: 350, + ProductName: 'Helsinki Bratwurst Traditional', + SupplierID: 10, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 182.5, + UnitsInStock: 52, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2002-08-08'), + }, + { + ProductID: 351, + ProductName: 'Tokyo Rocket Leaves Premium', + SupplierID: 11, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 18.5, + UnitsInStock: 71, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2007-04-20'), + }, + { + ProductID: 352, + ProductName: 'Tallinn Fruit Gums Gold', + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 20.95, + UnitsInStock: 25, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2019-10-01'), + }, + { + ProductID: 353, + ProductName: 'Bombay Sea Bass Gold', + SupplierID: 18, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 120.0, + UnitsInStock: 49, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2016-06-20'), + }, + { + ProductID: 354, + ProductName: 'Louisiana Smoked Ham Classic', + SupplierID: 10, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 229.5, + UnitsInStock: 79, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2011-02-10'), + }, + { + ProductID: 355, + ProductName: 'Nordsee Emmental Selection', + SupplierID: 8, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 15.75, + UnitsInStock: 50, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-01-24'), + }, + { + ProductID: 356, + ProductName: 'Helsinki King Prawns Reserve', + SupplierID: 5, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 207.25, + UnitsInStock: 53, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2011-03-07'), + }, + { + ProductID: 357, + ProductName: 'Bavarian Cheddar Blocks Deluxe', + SupplierID: 2, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 19.95, + UnitsInStock: 104, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2006-10-25'), + }, + { + ProductID: 358, + ProductName: 'Grandma Kellys Salsa Verde Reserve', + SupplierID: 6, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 102.95, + UnitsInStock: 105, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2012-12-07'), + }, + { + ProductID: 359, + ProductName: 'Cascade Quinoa', + SupplierID: 28, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 136.5, + UnitsInStock: 99, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2006-12-04'), + }, + { + ProductID: 360, + ProductName: 'Gustafs Buckwheat Classic', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 135.0, + UnitsInStock: 9, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2000-08-01'), + }, + { + ProductID: 361, + ProductName: 'Grandma Kellys Peanut Sauce Selection', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 187.75, + UnitsInStock: 8, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2000-05-24'), + }, + { + ProductID: 362, + ProductName: 'Porto Hazelnut Cream Classic', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 164.5, + UnitsInStock: 89, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-11-26'), + }, + { + ProductID: 363, + ProductName: 'Tallinn Baby Carrots Traditional', + SupplierID: 9, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 135.25, + UnitsInStock: 149, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-10-07'), + }, + { + ProductID: 364, + ProductName: 'Istanbul Fruit Gums Selection', + SupplierID: 17, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 114.75, + UnitsInStock: 57, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-10-09'), + }, + { + ProductID: 365, + ProductName: 'Bergen Cabernet Traditional', + SupplierID: 17, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 140.95, + UnitsInStock: 85, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2005-03-17'), + }, + { + ProductID: 366, + ProductName: 'Aberdeen Mustard Extra', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 211.25, + UnitsInStock: 131, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-07-22'), + }, + { + ProductID: 367, + ProductName: 'Andalusia Chai Blend Original', + SupplierID: 9, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 173.0, + UnitsInStock: 1, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-11-18'), + }, + { + ProductID: 368, + ProductName: 'Nordsee Caramel Wafers Reserve', + SupplierID: 2, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 22.25, + UnitsInStock: 20, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-05-23'), + }, + { + ProductID: 369, + ProductName: 'Dublin Soy Sauce Gold', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 167.25, + UnitsInStock: 21, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2006-06-18'), + }, + { + ProductID: 370, + ProductName: 'Verona Muesli Extra', + SupplierID: 2, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 129.5, + UnitsInStock: 23, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-12-26'), + }, + { + ProductID: 371, + ProductName: 'Santiago Anchovies Original', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 109.25, + UnitsInStock: 135, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2020-03-14'), + }, + { + ProductID: 372, + ProductName: 'Andalusia Ginger Root Extra', + SupplierID: 14, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 95.99, + UnitsInStock: 105, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2006-06-23'), + }, + { + ProductID: 373, + ProductName: 'Athens Cajun Rub Gold', + SupplierID: 23, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 138.25, + UnitsInStock: 42, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2002-03-03'), + }, + { + ProductID: 374, + ProductName: 'Bergen Sardines Extra', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 124.25, + UnitsInStock: 84, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2011-01-08'), + }, + { + ProductID: 375, + ProductName: 'Athens Peanut Sauce Traditional', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 220.5, + UnitsInStock: 32, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2008-02-01'), + }, + { + ProductID: 376, + ProductName: 'Zurich Sweet Corn Gold', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 160.25, + UnitsInStock: 32, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-07-05'), + }, + { + ProductID: 377, + ProductName: 'Seville Clams Reserve', + SupplierID: 21, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 148.75, + UnitsInStock: 54, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-05-22'), + }, + { + ProductID: 378, + ProductName: 'Tokyo Avocados Reserve', + SupplierID: 9, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 8.95, + UnitsInStock: 148, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-06-16'), + }, + { + ProductID: 379, + ProductName: 'Shanghai Scallops Selection', + SupplierID: 12, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 209.5, + UnitsInStock: 75, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2001-11-22'), + }, + { + ProductID: 380, + ProductName: 'Zurich Artichoke Hearts Original', + SupplierID: 10, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 221.75, + UnitsInStock: 31, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2001-03-08'), + }, + { + ProductID: 381, + ProductName: 'Tallinn Shortbread Extra', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 222.5, + UnitsInStock: 133, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2015-09-09'), + }, + { + ProductID: 382, + ProductName: 'Pavlova Brownie Bites Gold', + SupplierID: 23, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 148.0, + UnitsInStock: 7, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2018-09-20'), + }, + { + ProductID: 383, + ProductName: 'Escargot Pomegranates', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 121.75, + UnitsInStock: 140, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-01-26'), + }, + { + ProductID: 384, + ProductName: 'Alpen Caramel Wafers Deluxe', + SupplierID: 24, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 111.25, + UnitsInStock: 89, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2001-07-13'), + }, + { + ProductID: 385, + ProductName: 'Provence Egg Noodles Deluxe', + SupplierID: 14, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 9.25, + UnitsInStock: 46, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2013-10-04'), + }, + { + ProductID: 386, + ProductName: 'Athens Smoked Ham Gold', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 50.99, + UnitsInStock: 1, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2001-10-22'), + }, + { + ProductID: 387, + ProductName: 'Odessa Ale Classic', + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 150.99, + UnitsInStock: 15, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-08-05'), + }, + { + ProductID: 388, + ProductName: 'Gustafs Apple Juice Premium', + SupplierID: 7, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 33.95, + UnitsInStock: 143, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2005-01-04'), + }, + { + ProductID: 389, + ProductName: 'Cascade Dried Apples Reserve', + SupplierID: 26, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 41.5, + UnitsInStock: 127, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-02-24'), + }, + { + ProductID: 390, + ProductName: 'Bavarian Marinade Premium', + SupplierID: 21, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 61.0, + UnitsInStock: 146, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-12-06'), + }, + { + ProductID: 391, + ProductName: 'Odessa Pastrami Traditional', + SupplierID: 27, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 222.0, + UnitsInStock: 53, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2002-12-15'), + }, + { + ProductID: 392, + ProductName: 'Salzburg Chili Sauce Premium', + SupplierID: 27, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 55.5, + UnitsInStock: 61, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2004-04-25'), + }, + { + ProductID: 393, + ProductName: 'Lisbon Beef Jerky Extra', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 103.0, + UnitsInStock: 30, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2006-08-22'), + }, + { + ProductID: 394, + ProductName: 'Marrakesh Cola Original', + SupplierID: 6, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 210.0, + UnitsInStock: 114, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2015-09-04'), + }, + { + ProductID: 395, + ProductName: 'Istanbul Green Tea Reserve', + SupplierID: 27, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 51.75, + UnitsInStock: 36, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-08-05'), + }, + { + ProductID: 396, + ProductName: 'Utrecht Penne Classic', + SupplierID: 25, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 163.25, + UnitsInStock: 18, + UnitsOnOrder: 15, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2019-06-07'), + }, + { + ProductID: 397, + ProductName: 'Lima Stout Classic', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 103.99, + UnitsInStock: 36, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2018-04-08'), + }, + { + ProductID: 398, + ProductName: 'Naples Herring Fillets Deluxe', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 238.75, + UnitsInStock: 49, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2017-12-05'), + }, + { + ProductID: 399, + ProductName: 'Helsinki Truffle Oil Extra', + SupplierID: 12, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 207.25, + UnitsInStock: 62, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2019-11-20'), + }, + { + ProductID: 400, + ProductName: 'Aberdeen Octopus Premium', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 160.99, + UnitsInStock: 4, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-09-22'), + }, + { + ProductID: 401, + ProductName: 'Pavlova Cheddar Blocks Gold', + SupplierID: 4, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 163.0, + UnitsInStock: 90, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-09-24'), + }, + { + ProductID: 402, + ProductName: 'Lima Sardines Traditional', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 68.25, + UnitsInStock: 148, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2008-02-22'), + }, + { + ProductID: 403, + ProductName: 'Utrecht Sparkling Water Premium', + SupplierID: 11, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 88.95, + UnitsInStock: 89, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2009-02-27'), + }, + { + ProductID: 404, + ProductName: 'Salzburg Squid Rings Classic', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 86.5, + UnitsInStock: 44, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2019-07-02'), + }, + { + ProductID: 405, + ProductName: 'Tallinn Salsa Verde Deluxe', + SupplierID: 19, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 53.95, + UnitsInStock: 8, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2009-09-11'), + }, + { + ProductID: 406, + ProductName: 'Naples Mango Nectar Gold', + SupplierID: 9, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 54.75, + UnitsInStock: 147, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2003-12-20'), + }, + { + ProductID: 407, + ProductName: 'Lisbon Wasabi Paste Classic', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 122.25, + UnitsInStock: 144, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-04-24'), + }, + { + ProductID: 408, + ProductName: 'Cascade Parmesan Shavings Extra', + SupplierID: 10, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 19.25, + UnitsInStock: 36, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2003-02-04'), + }, + { + ProductID: 409, + ProductName: 'Pavlova Ginger Root Reserve', + SupplierID: 11, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 139.0, + UnitsInStock: 68, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2012-03-27'), + }, + { + ProductID: 410, + ProductName: 'Ghent Almond Biscotti Selection', + SupplierID: 18, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 219.5, + UnitsInStock: 70, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2017-02-06'), + }, + { + ProductID: 411, + ProductName: 'Bordeaux Penne Deluxe', + SupplierID: 22, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 214.5, + UnitsInStock: 65, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2012-10-28'), + }, + { + ProductID: 412, + ProductName: 'Cascade Clams Deluxe', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 101.5, + UnitsInStock: 31, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2020-05-25'), + }, + { + ProductID: 413, + ProductName: 'Louisiana Buckwheat', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 215.0, + UnitsInStock: 95, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2001-09-22'), + }, + { + ProductID: 414, + ProductName: 'Cascade Coconut Bars Extra', + SupplierID: 2, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 69.25, + UnitsInStock: 122, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2010-10-06'), + }, + { + ProductID: 415, + ProductName: 'Odessa Veal Cutlets Premium', + SupplierID: 11, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 220.99, + UnitsInStock: 84, + UnitsOnOrder: 50, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-08-18'), + }, + { + ProductID: 416, + ProductName: 'Cascade Cheddar Blocks Reserve', + SupplierID: 25, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 117.75, + UnitsInStock: 60, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2006-08-25'), + }, + { + ProductID: 417, + ProductName: 'Bombay Fish Sauce Extra', + SupplierID: 10, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 187.0, + UnitsInStock: 120, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2018-02-07'), + }, + { + ProductID: 418, + ProductName: 'Grandma Kellys Shallots Premium', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 160.75, + UnitsInStock: 111, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-06-07'), + }, + { + ProductID: 419, + ProductName: 'Ghent Curry Paste Premium', + SupplierID: 28, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 146.75, + UnitsInStock: 147, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2011-11-05'), + }, + { + ProductID: 420, + ProductName: 'Chef Antons Veal Cutlets', + SupplierID: 13, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 28.25, + UnitsInStock: 109, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2003-08-01'), + }, + { + ProductID: 421, + ProductName: 'Bavarian Oysters Classic', + SupplierID: 17, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 198.99, + UnitsInStock: 75, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2011-06-22'), + }, + { + ProductID: 422, + ProductName: 'Tallinn Sardines', + SupplierID: 9, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 132.0, + UnitsInStock: 23, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2015-02-22'), + }, + { + ProductID: 423, + ProductName: 'Helsinki Cola Reserve', + SupplierID: 8, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 181.75, + UnitsInStock: 46, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-02-09'), + }, + { + ProductID: 424, + ProductName: 'Andalusia Pearl Barley Reserve', + SupplierID: 26, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 135.25, + UnitsInStock: 113, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-09-11'), + }, + { + ProductID: 425, + ProductName: 'Oslo Octopus Traditional', + SupplierID: 9, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 51.5, + UnitsInStock: 97, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-04-09'), + }, + { + ProductID: 426, + ProductName: 'Chef Antons Penne Reserve', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 226.5, + UnitsInStock: 61, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2012-01-03'), + }, + { + ProductID: 427, + ProductName: 'Chef Antons Chorizo Reserve', + SupplierID: 14, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 25.25, + UnitsInStock: 52, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2000-02-05'), + }, + { + ProductID: 428, + ProductName: 'Highland Ketchup Premium', + SupplierID: 7, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 149.25, + UnitsInStock: 129, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2012-02-26'), + }, + { + ProductID: 429, + ProductName: 'Alpen Toffee Gold', + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 22.95, + UnitsInStock: 31, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2004-04-03'), + }, + { + ProductID: 430, + ProductName: 'Odessa Bacon Strips Extra', + SupplierID: 9, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 184.25, + UnitsInStock: 14, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2009-02-13'), + }, + { + ProductID: 431, + ProductName: 'Zurich Macaroons Deluxe', + SupplierID: 24, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 5.25, + UnitsInStock: 123, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-05-05'), + }, + { + ProductID: 432, + ProductName: 'Aberdeen Quark', + SupplierID: 16, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 89.99, + UnitsInStock: 26, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-09-19'), + }, + { + ProductID: 433, + ProductName: 'Tokyo Apple Juice Original', + SupplierID: 7, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 176.95, + UnitsInStock: 136, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2003-07-01'), + }, + { + ProductID: 434, + ProductName: 'Santiago Soy Sauce Extra', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 92.25, + UnitsInStock: 101, + UnitsOnOrder: 25, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2008-11-24'), + }, + { + ProductID: 435, + ProductName: 'Chef Antons Apple Juice Original', + SupplierID: 19, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 226.0, + UnitsInStock: 70, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-02-13'), + }, + { + ProductID: 436, + ProductName: 'Odessa Mackerel Extra', + SupplierID: 10, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 19.95, + UnitsInStock: 106, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2002-04-17'), + }, + { + ProductID: 437, + ProductName: 'Marrakesh Sun Dried Tomatoes Gold', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 204.75, + UnitsInStock: 100, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2003-01-20'), + }, + { + ProductID: 438, + ProductName: 'Andalusia Rib Roast Gold', + SupplierID: 7, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 25.75, + UnitsInStock: 118, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2000-10-11'), + }, + { + ProductID: 439, + ProductName: 'Vienna Sausage Links Traditional', + SupplierID: 24, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 59.25, + UnitsInStock: 41, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2003-01-14'), + }, + { + ProductID: 440, + ProductName: 'Tokyo Muesli Deluxe', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 48.0, + UnitsInStock: 6, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-09-05'), + }, + { + ProductID: 441, + ProductName: 'Aberdeen Herring Fillets Original', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 188.99, + UnitsInStock: 129, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2011-12-02'), + }, + { + ProductID: 442, + ProductName: 'Escargot Licorice Drops Original', + SupplierID: 19, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 114.0, + UnitsInStock: 33, + UnitsOnOrder: 50, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2004-04-14'), + }, + { + ProductID: 443, + ProductName: 'Pavlova Horseradish Deluxe', + SupplierID: 10, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 105.99, + UnitsInStock: 89, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2014-02-09'), + }, + { + ProductID: 444, + ProductName: 'Krakow Ginger Root Traditional', + SupplierID: 22, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 50.25, + UnitsInStock: 13, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-10-11'), + }, + { + ProductID: 445, + ProductName: 'Valencia Buckwheat Classic', + SupplierID: 19, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 97.5, + UnitsInStock: 126, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-01-23'), + }, + { + ProductID: 446, + ProductName: 'Tallinn Mayonnaise Deluxe', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 155.0, + UnitsInStock: 144, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2013-11-18'), + }, + { + ProductID: 447, + ProductName: 'Nordsee Whole Wheat Flour Selection', + SupplierID: 19, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 117.0, + UnitsInStock: 20, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2007-09-25'), + }, + { + ProductID: 448, + ProductName: 'Utrecht Marzipan Deluxe', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 184.99, + UnitsInStock: 22, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2005-09-16'), + }, + { + ProductID: 449, + ProductName: 'Tokyo Fish Sauce Premium', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 190.95, + UnitsInStock: 34, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2000-01-18'), + }, + { + ProductID: 450, + ProductName: 'Utrecht Gingerbread Gold', + SupplierID: 14, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 23.25, + UnitsInStock: 19, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2008-08-07'), + }, + { + ProductID: 451, + ProductName: 'Helsinki Portobello Mushrooms Premium', + SupplierID: 22, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 212.75, + UnitsInStock: 128, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2006-10-17'), + }, + { + ProductID: 452, + ProductName: 'Lisbon Cabernet Extra', + SupplierID: 5, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 99.95, + UnitsInStock: 119, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2016-12-28'), + }, + { + ProductID: 453, + ProductName: 'Bordeaux Pearl Barley Reserve', + SupplierID: 18, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 119.99, + UnitsInStock: 144, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2018-12-04'), + }, + { + ProductID: 454, + ProductName: 'Krakow Gouda Extra', + SupplierID: 25, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 132.25, + UnitsInStock: 110, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2020-03-23'), + }, + { + ProductID: 455, + ProductName: 'Sicilian Butter Reserve', + SupplierID: 2, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 102.25, + UnitsInStock: 63, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2005-04-18'), + }, + { + ProductID: 456, + ProductName: 'Uncle Bobs Red Peppers Classic', + SupplierID: 9, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 51.95, + UnitsInStock: 148, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-10-10'), + }, + { + ProductID: 457, + ProductName: 'Sicilian Basmati Rice Traditional', + SupplierID: 14, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 225.0, + UnitsInStock: 70, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2009-11-19'), + }, + { + ProductID: 458, + ProductName: 'Alpen Red Peppers Original', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 107.95, + UnitsInStock: 80, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2014-05-26'), + }, + { + ProductID: 459, + ProductName: 'Seville Polenta Traditional', + SupplierID: 23, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 38.75, + UnitsInStock: 50, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2000-02-16'), + }, + { + ProductID: 460, + ProductName: 'Helsinki Sparkling Water Reserve', + SupplierID: 28, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 33.99, + UnitsInStock: 60, + UnitsOnOrder: 20, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2005-02-24'), + }, + { + ProductID: 461, + ProductName: 'Tokyo Lemons Selection', + SupplierID: 26, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 68.0, + UnitsInStock: 36, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2009-09-27'), + }, + { + ProductID: 462, + ProductName: 'Lima Fruit Gums Extra', + SupplierID: 4, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 143.99, + UnitsInStock: 118, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2011-01-06'), + }, + { + ProductID: 463, + ProductName: 'Vienna Coconut Bars Deluxe', + SupplierID: 2, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 27.25, + UnitsInStock: 12, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-03-15'), + }, + { + ProductID: 464, + ProductName: 'Zurich Almond Biscotti Extra', + SupplierID: 9, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 203.99, + UnitsInStock: 84, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2002-02-15'), + }, + { + ProductID: 465, + ProductName: 'Malaga Cheddar Blocks Classic', + SupplierID: 4, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 78.25, + UnitsInStock: 4, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-11-09'), + }, + { + ProductID: 466, + ProductName: 'Grandma Kellys Sparkling Water Gold', + SupplierID: 6, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 96.75, + UnitsInStock: 93, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2018-06-11'), + }, + { + ProductID: 467, + ProductName: 'Ghent Almond Biscotti', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 174.5, + UnitsInStock: 86, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2020-03-17'), + }, + { + ProductID: 468, + ProductName: 'Highland Mayonnaise Premium', + SupplierID: 5, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 42.0, + UnitsInStock: 25, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-12-17'), + }, + { + ProductID: 469, + ProductName: 'Sicilian Cajun Rub Classic', + SupplierID: 4, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 139.75, + UnitsInStock: 9, + UnitsOnOrder: 10, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-05-02'), + }, + { + ProductID: 470, + ProductName: 'Kyoto Trout Fillets Original', + SupplierID: 7, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 88.95, + UnitsInStock: 75, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-11-19'), + }, + { + ProductID: 471, + ProductName: 'Cairo Muesli Original', + SupplierID: 6, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 50.95, + UnitsInStock: 118, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-04-17'), + }, + { + ProductID: 472, + ProductName: 'Riga Mascarpone Original', + SupplierID: 2, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 16.95, + UnitsInStock: 121, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2008-04-22'), + }, + { + ProductID: 473, + ProductName: 'Krakow Salami Gold', + SupplierID: 16, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 214.75, + UnitsInStock: 54, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2016-03-13'), + }, + { + ProductID: 474, + ProductName: 'Louisiana Marzipan Extra', + SupplierID: 23, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 139.99, + UnitsInStock: 116, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2020-03-09'), + }, + { + ProductID: 475, + ProductName: 'Sicilian Creme Fraiche Selection', + SupplierID: 7, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 37.75, + UnitsInStock: 34, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2012-12-20'), + }, + { + ProductID: 476, + ProductName: 'Kyoto Pesto Extra', + SupplierID: 6, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 52.5, + UnitsInStock: 17, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2003-11-26'), + }, + { + ProductID: 477, + ProductName: 'Salzburg Brie Wheel Reserve', + SupplierID: 10, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 102.99, + UnitsInStock: 114, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2007-10-12'), + }, + { + ProductID: 478, + ProductName: 'Bombay Lamb Chops Classic', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 150.5, + UnitsInStock: 129, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-02-22'), + }, + { + ProductID: 479, + ProductName: 'Shanghai King Prawns Deluxe', + SupplierID: 11, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 107.5, + UnitsInStock: 31, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2013-09-11'), + }, + { + ProductID: 480, + ProductName: 'Bordeaux Sausage Links Reserve', + SupplierID: 4, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 193.5, + UnitsInStock: 57, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2008-02-17'), + }, + { + ProductID: 481, + ProductName: 'Dublin Rice Crackers Extra', + SupplierID: 15, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 173.5, + UnitsInStock: 1, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2009-12-12'), + }, + { + ProductID: 482, + ProductName: 'Sicilian Sausage Links Original', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 39.25, + UnitsInStock: 73, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-03-08'), + }, + { + ProductID: 483, + ProductName: 'Zurich Cheddar Blocks Deluxe', + SupplierID: 7, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 127.5, + UnitsInStock: 103, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2013-10-02'), + }, + { + ProductID: 484, + ProductName: 'Bombay Tortillas Original', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 50.0, + UnitsInStock: 53, + UnitsOnOrder: 15, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-07-13'), + }, + { + ProductID: 485, + ProductName: 'Valencia Cheddar Blocks Selection', + SupplierID: 12, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 179.99, + UnitsInStock: 95, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-12-15'), + }, + { + ProductID: 486, + ProductName: 'Athens King Prawns Reserve', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 142.25, + UnitsInStock: 142, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2002-10-18'), + }, + { + ProductID: 487, + ProductName: 'Sicilian Ricotta Traditional', + SupplierID: 5, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 196.75, + UnitsInStock: 108, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2011-12-16'), + }, + { + ProductID: 488, + ProductName: 'Riga Pesto Deluxe', + SupplierID: 26, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 32.95, + UnitsInStock: 129, + UnitsOnOrder: 50, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2020-07-01'), + }, + { + ProductID: 489, + ProductName: 'Alpen Lager Extra', + SupplierID: 15, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 41.75, + UnitsInStock: 149, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-12-07'), + }, + { + ProductID: 490, + ProductName: 'Seville Truffle Oil Gold', + SupplierID: 20, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 135.75, + UnitsInStock: 65, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-10-18'), + }, + { + ProductID: 491, + ProductName: 'Bombay Crab Meat Original', + SupplierID: 7, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 35.95, + UnitsInStock: 102, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-11-17'), + }, + { + ProductID: 492, + ProductName: 'Louisiana Brownie Bites', + SupplierID: 10, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 112.99, + UnitsInStock: 64, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2004-09-19'), + }, + { + ProductID: 493, + ProductName: 'Porto Pate Gold', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 3.95, + UnitsInStock: 117, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-01-11'), + }, + { + ProductID: 494, + ProductName: 'Aberdeen Prosciutto Traditional', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 190.75, + UnitsInStock: 101, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2008-01-21'), + }, + { + ProductID: 495, + ProductName: 'Vienna Oat Flakes Gold', + SupplierID: 5, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 202.99, + UnitsInStock: 113, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2020-06-13'), + }, + { + ProductID: 496, + ProductName: 'Cascade Clams Traditional', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 127.95, + UnitsInStock: 97, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-04-07'), + }, + { + ProductID: 497, + ProductName: 'Uncle Bobs Shallots Traditional', + SupplierID: 9, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 67.5, + UnitsInStock: 149, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-04-24'), + }, + { + ProductID: 498, + ProductName: 'Cairo Truffle Oil Traditional', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 62.25, + UnitsInStock: 70, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2007-06-02'), + }, + { + ProductID: 499, + ProductName: 'Helsinki Chocolate Truffles Deluxe', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 160.99, + UnitsInStock: 51, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-01-10'), + }, + { + ProductID: 500, + ProductName: 'Copenhagen Squid Rings Premium', + SupplierID: 26, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 202.5, + UnitsInStock: 61, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-09-25'), + }, + { + ProductID: 501, + ProductName: 'Provence Meatballs Extra', + SupplierID: 7, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 51.95, + UnitsInStock: 46, + UnitsOnOrder: 60, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2002-05-09'), + }, + { + ProductID: 502, + ProductName: 'Tallinn Salami Traditional', + SupplierID: 9, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 140.75, + UnitsInStock: 22, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2013-04-13'), + }, + { + ProductID: 503, + ProductName: 'Odessa Baby Spinach', + SupplierID: 7, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 208.99, + UnitsInStock: 138, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2016-06-21'), + }, + { + ProductID: 504, + ProductName: 'Cairo Barley Water Original', + SupplierID: 11, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 97.25, + UnitsInStock: 117, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-10-28'), + }, + { + ProductID: 505, + ProductName: 'Gustafs Praline Mix Reserve', + SupplierID: 14, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 15.95, + UnitsInStock: 139, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2014-10-21'), + }, + { + ProductID: 506, + ProductName: 'Dublin Macaroons Traditional', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 77.75, + UnitsInStock: 33, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2016-09-06'), + }, + { + ProductID: 507, + ProductName: 'Krakow Scallops Selection', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 120.25, + UnitsInStock: 121, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2005-02-02'), + }, + { + ProductID: 508, + ProductName: 'Naples Lamb Chops Selection', + SupplierID: 6, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 98.25, + UnitsInStock: 147, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2001-07-25'), + }, + { + ProductID: 509, + ProductName: 'Toscana Crab Meat Extra', + SupplierID: 7, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 197.99, + UnitsInStock: 10, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2000-05-16'), + }, + { + ProductID: 510, + ProductName: 'Odessa Cocoa Drink Premium', + SupplierID: 17, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 115.0, + UnitsInStock: 72, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2015-01-08'), + }, + { + ProductID: 511, + ProductName: 'Vienna Anchovies Reserve', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 48.25, + UnitsInStock: 90, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2012-01-01'), + }, + { + ProductID: 512, + ProductName: 'Vienna Balsamic Vinegar', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 184.0, + UnitsInStock: 0, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2007-02-06'), + }, + { + ProductID: 513, + ProductName: 'Sicilian Whole Wheat Flour Gold', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 186.99, + UnitsInStock: 90, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2005-05-23'), + }, + { + ProductID: 514, + ProductName: 'Toscana Wasabi Paste Traditional', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 138.99, + UnitsInStock: 1, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2019-01-11'), + }, + { + ProductID: 515, + ProductName: 'Pavlova Cajun Rub Gold', + SupplierID: 13, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 23.25, + UnitsInStock: 2, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2011-07-07'), + }, + { + ProductID: 516, + ProductName: 'Marrakesh Halloumi Gold', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 215.99, + UnitsInStock: 71, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-02-18'), + }, + { + ProductID: 517, + ProductName: 'Riga Lager Extra', + SupplierID: 18, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 235.75, + UnitsInStock: 77, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2013-01-12'), + }, + { + ProductID: 518, + ProductName: 'Porto Lemons Original', + SupplierID: 25, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 196.0, + UnitsInStock: 28, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-10-13'), + }, + { + ProductID: 519, + ProductName: 'Cairo Camembert Selection', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 124.0, + UnitsInStock: 115, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-01-26'), + }, + { + ProductID: 520, + ProductName: 'Toscana Sparkling Water Deluxe', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 236.25, + UnitsInStock: 19, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2009-08-12'), + }, + { + ProductID: 521, + ProductName: 'Copenhagen Avocados Extra', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 147.95, + UnitsInStock: 12, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2014-01-24'), + }, + { + ProductID: 522, + ProductName: 'Naples Rib Roast Reserve', + SupplierID: 27, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 214.75, + UnitsInStock: 146, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2016-10-06'), + }, + { + ProductID: 523, + ProductName: 'Pavlova Granola Premium', + SupplierID: 24, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 116.75, + UnitsInStock: 55, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2009-04-03'), + }, + { + ProductID: 524, + ProductName: 'Istanbul Fruit Gums Gold', + SupplierID: 10, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 216.0, + UnitsInStock: 75, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2001-11-10'), + }, + { + ProductID: 525, + ProductName: 'Helsinki Blue Cheese Original', + SupplierID: 10, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 236.75, + UnitsInStock: 137, + UnitsOnOrder: 15, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2013-07-05'), + }, + { + ProductID: 526, + ProductName: 'Dublin Whipping Cream Original', + SupplierID: 9, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 225.25, + UnitsInStock: 147, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2010-05-07'), + }, + { + ProductID: 527, + ProductName: 'Verona Fruit Gums Selection', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 120.5, + UnitsInStock: 132, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-09-06'), + }, + { + ProductID: 528, + ProductName: 'Nordsee Black Pudding Selection', + SupplierID: 14, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 6.25, + UnitsInStock: 36, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2011-04-17'), + }, + { + ProductID: 529, + ProductName: 'Bombay Prosciutto Deluxe', + SupplierID: 5, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 175.0, + UnitsInStock: 135, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2011-02-19'), + }, + { + ProductID: 530, + ProductName: 'Andalusia Sardines Extra', + SupplierID: 5, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 172.25, + UnitsInStock: 16, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2016-04-11'), + }, + { + ProductID: 531, + ProductName: 'Pavlova Barbecue Sauce Reserve', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 110.99, + UnitsInStock: 100, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2011-05-10'), + }, + { + ProductID: 532, + ProductName: 'Dublin Truffle Oil Deluxe', + SupplierID: 15, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 168.75, + UnitsInStock: 54, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-03-26'), + }, + { + ProductID: 533, + ProductName: 'Malaga Wasabi Paste Extra', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 45.0, + UnitsInStock: 149, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-05-11'), + }, + { + ProductID: 534, + ProductName: 'Escargot Lemons Extra', + SupplierID: 13, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 234.5, + UnitsInStock: 82, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2001-05-07'), + }, + { + ProductID: 535, + ProductName: 'Santiago Veal Cutlets Traditional', + SupplierID: 22, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 87.75, + UnitsInStock: 5, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-05-20'), + }, + { + ProductID: 536, + ProductName: 'Alpen Portobello Mushrooms Deluxe', + SupplierID: 16, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 188.0, + UnitsInStock: 35, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-05-21'), + }, + { + ProductID: 537, + ProductName: 'Utrecht Kombucha Gold', + SupplierID: 24, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 29.0, + UnitsInStock: 76, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2018-05-11'), + }, + { + ProductID: 538, + ProductName: 'Ravenna Shallots Deluxe', + SupplierID: 20, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 238.95, + UnitsInStock: 109, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2007-05-05'), + }, + { + ProductID: 539, + ProductName: 'Utrecht Couscous Classic', + SupplierID: 11, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 117.5, + UnitsInStock: 2, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-12-20'), + }, + { + ProductID: 540, + ProductName: 'Tokyo Black Pudding Gold', + SupplierID: 8, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 17.99, + UnitsInStock: 81, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-08-26'), + }, + { + ProductID: 541, + ProductName: 'Zurich Barbecue Sauce Gold', + SupplierID: 4, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 201.75, + UnitsInStock: 92, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2000-12-07'), + }, + { + ProductID: 542, + ProductName: 'Valencia Smoked Salmon Classic', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 6.0, + UnitsInStock: 108, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-04-24'), + }, + { + ProductID: 543, + ProductName: 'Verona Fudge Squares Traditional', + SupplierID: 24, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 11.99, + UnitsInStock: 123, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-03-06'), + }, + { + ProductID: 544, + ProductName: 'Utrecht Chardonnay Reserve', + SupplierID: 26, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 94.0, + UnitsInStock: 29, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-02-04'), + }, + { + ProductID: 545, + ProductName: 'Highland Mayonnaise Reserve', + SupplierID: 9, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 100.5, + UnitsInStock: 45, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2008-06-14'), + }, + { + ProductID: 546, + ProductName: 'Bombay Camembert Original', + SupplierID: 1, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 224.25, + UnitsInStock: 139, + UnitsOnOrder: 100, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2016-05-07'), + }, + { + ProductID: 547, + ProductName: 'Valencia Muesli Selection', + SupplierID: 18, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 80.5, + UnitsInStock: 82, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2008-11-24'), + }, + { + ProductID: 548, + ProductName: 'Helsinki Dried Figs Selection', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 28.25, + UnitsInStock: 101, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-05-03'), + }, + { + ProductID: 549, + ProductName: 'Lisbon Ale Deluxe', + SupplierID: 11, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 207.5, + UnitsInStock: 126, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2000-12-07'), + }, + { + ProductID: 550, + ProductName: 'Bergen Blue Cheese Original', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 7.75, + UnitsInStock: 119, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2006-11-23'), + }, + { + ProductID: 551, + ProductName: 'Alpen Stout Premium', + SupplierID: 13, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 86.5, + UnitsInStock: 148, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2001-03-05'), + }, + { + ProductID: 552, + ProductName: 'Copenhagen Clams Original', + SupplierID: 17, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 141.75, + UnitsInStock: 147, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-05-02'), + }, + { + ProductID: 553, + ProductName: 'Seville Sausage Links Traditional', + SupplierID: 5, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 44.99, + UnitsInStock: 23, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2018-01-21'), + }, + { + ProductID: 554, + ProductName: 'Marrakesh Wasabi Paste Selection', + SupplierID: 10, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 13.0, + UnitsInStock: 126, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2011-09-06'), + }, + { + ProductID: 555, + ProductName: 'Kyoto Herring Fillets Reserve', + SupplierID: 16, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 79.95, + UnitsInStock: 24, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-04-24'), + }, + { + ProductID: 556, + ProductName: 'Toscana Caviar', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 106.95, + UnitsInStock: 112, + UnitsOnOrder: 60, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2017-06-08'), + }, + { + ProductID: 557, + ProductName: 'Alpen Lemonade Premium', + SupplierID: 28, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 31.95, + UnitsInStock: 61, + UnitsOnOrder: 50, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2012-12-05'), + }, + { + ProductID: 558, + ProductName: 'Bergen Caviar Classic', + SupplierID: 17, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 134.0, + UnitsInStock: 109, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2008-04-04'), + }, + { + ProductID: 559, + ProductName: 'Pavlova Semolina Classic', + SupplierID: 6, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 63.5, + UnitsInStock: 67, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2001-04-11'), + }, + { + ProductID: 560, + ProductName: 'Aberdeen Kefir Premium', + SupplierID: 4, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 220.75, + UnitsInStock: 135, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2008-11-26'), + }, + { + ProductID: 561, + ProductName: 'Graz Smoked Ham Farmhouse', + SupplierID: 27, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 44.99, + UnitsInStock: 50, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-03-23'), + }, + { + ProductID: 562, + ProductName: 'Krakow Whipping Cream Gold', + SupplierID: 16, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 101.95, + UnitsInStock: 74, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-07-17'), + }, + { + ProductID: 563, + ProductName: 'Gustafs Shortbread Farmhouse', + SupplierID: 27, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 124.99, + UnitsInStock: 69, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2018-12-06'), + }, + { + ProductID: 564, + ProductName: 'Porto Espresso Blend Artisan', + SupplierID: 6, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 159.95, + UnitsInStock: 96, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2001-08-13'), + }, + { + ProductID: 565, + ProductName: 'Salzburg Duck Confit Deluxe', + SupplierID: 4, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 27.0, + UnitsInStock: 5, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-01-16'), + }, + { + ProductID: 566, + ProductName: 'Granada Apple Juice', + SupplierID: 28, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 108.99, + UnitsInStock: 114, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2003-03-26'), + }, + { + ProductID: 567, + ProductName: 'Bordeaux Pastrami Classic', + SupplierID: 9, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 89.99, + UnitsInStock: 105, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-04-05'), + }, + { + ProductID: 568, + ProductName: 'Zagreb Spelt Flour Original', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 34.99, + UnitsInStock: 136, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2008-04-04'), + }, + { + ProductID: 569, + ProductName: 'Zagreb Brownie Bites Selection', + SupplierID: 27, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 3.25, + UnitsInStock: 3, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-05-19'), + }, + { + ProductID: 570, + ProductName: 'Tokyo Apple Juice Classic', + SupplierID: 26, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 40.75, + UnitsInStock: 55, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2003-08-28'), + }, + { + ProductID: 571, + ProductName: 'Montreal Smoked Ham', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 9.5, + UnitsInStock: 55, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-12-09'), + }, + { + ProductID: 572, + ProductName: 'Montreal Lobster Tails Traditional', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 126.5, + UnitsInStock: 115, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2006-05-28'), + }, + { + ProductID: 573, + ProductName: 'Dublin Beef Jerky Traditional', + SupplierID: 24, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 109.0, + UnitsInStock: 44, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2010-02-08'), + }, + { + ProductID: 574, + ProductName: 'Shanghai Bacon Strips Selection', + SupplierID: 1, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 134.0, + UnitsInStock: 60, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-07-10'), + }, + { + ProductID: 575, + ProductName: 'Bombay Caramel Wafers Selection', + SupplierID: 27, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 177.99, + UnitsInStock: 24, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2013-06-09'), + }, + { + ProductID: 576, + ProductName: 'Andalusia Barley Water Reserve', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 187.75, + UnitsInStock: 122, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2017-03-15'), + }, + { + ProductID: 577, + ProductName: 'Riga Whole Wheat Flour Classic', + SupplierID: 26, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 11.5, + UnitsInStock: 121, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-08-09'), + }, + { + ProductID: 578, + ProductName: 'Nordsee Rib Roast Original', + SupplierID: 9, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 68.75, + UnitsInStock: 57, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-02-02'), + }, + { + ProductID: 579, + ProductName: 'Oslo Mayonnaise Selection', + SupplierID: 27, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 100.95, + UnitsInStock: 31, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2008-03-21'), + }, + { + ProductID: 580, + ProductName: 'Genoa Smoked Ham Deluxe', + SupplierID: 22, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 18.0, + UnitsInStock: 76, + UnitsOnOrder: 25, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2009-08-23'), + }, + { + ProductID: 581, + ProductName: 'Ravenna Chili Sauce Gold', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 117.95, + UnitsInStock: 41, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2014-07-07'), + }, + { + ProductID: 582, + ProductName: 'Istanbul Emmental Selection', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 7.0, + UnitsInStock: 106, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2009-03-16'), + }, + { + ProductID: 583, + ProductName: 'Tokyo Semolina Deluxe', + SupplierID: 17, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 137.99, + UnitsInStock: 76, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-05-18'), + }, + { + ProductID: 584, + ProductName: 'Ljubljana Elderflower Cordial Selection', + SupplierID: 3, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 173.99, + UnitsInStock: 126, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2010-05-01'), + }, + { + ProductID: 585, + ProductName: 'Shanghai Plaice Fillets Deluxe', + SupplierID: 24, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 228.0, + UnitsInStock: 32, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2017-10-16'), + }, + { + ProductID: 586, + ProductName: 'Gdansk Whipping Cream Classic', + SupplierID: 9, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 44.75, + UnitsInStock: 121, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-03-23'), + }, + { + ProductID: 587, + ProductName: 'Sofia Licorice Drops Reserve', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 24.0, + UnitsInStock: 130, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2003-09-21'), + }, + { + ProductID: 588, + ProductName: 'Grandma Kellys Ginger Beer', + SupplierID: 23, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 224.99, + UnitsInStock: 95, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2004-04-10'), + }, + { + ProductID: 589, + ProductName: 'Bavarian Quinoa Artisan', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 195.99, + UnitsInStock: 54, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2017-11-05'), + }, + { + ProductID: 590, + ProductName: 'Ghent Tortillas Extra', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 201.95, + UnitsInStock: 57, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2005-01-06'), + }, + { + ProductID: 591, + ProductName: 'Lima Tahini Extra', + SupplierID: 22, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 71.5, + UnitsInStock: 11, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-03-01'), + }, + { + ProductID: 592, + ProductName: 'Ravenna Peanut Sauce Deluxe', + SupplierID: 23, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 226.25, + UnitsInStock: 46, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-05-14'), + }, + { + ProductID: 593, + ProductName: 'Nantes Stout Artisan', + SupplierID: 24, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 143.95, + UnitsInStock: 93, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2015-06-18'), + }, + { + ProductID: 594, + ProductName: 'Dublin Bratwurst', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 106.95, + UnitsInStock: 150, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2008-02-23'), + }, + { + ProductID: 595, + ProductName: 'Provence Goat Cheese Selection', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 181.75, + UnitsInStock: 70, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-11-15'), + }, + { + ProductID: 596, + ProductName: 'Copenhagen Shallots Extra', + SupplierID: 27, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 206.5, + UnitsInStock: 38, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2008-03-14'), + }, + { + ProductID: 597, + ProductName: 'Porto Mint Creams Artisan', + SupplierID: 9, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 20.99, + UnitsInStock: 130, + UnitsOnOrder: 20, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2009-05-12'), + }, + { + ProductID: 598, + ProductName: 'Bruges Buttermilk Extra', + SupplierID: 3, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 109.0, + UnitsInStock: 19, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2009-10-25'), + }, + { + ProductID: 599, + ProductName: 'Shanghai Manchego Classic', + SupplierID: 10, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 28.75, + UnitsInStock: 96, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2020-04-08'), + }, + { + ProductID: 600, + ProductName: 'Bombay Chili Sauce Selection', + SupplierID: 25, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 140.0, + UnitsInStock: 130, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2000-01-05'), + }, + { + ProductID: 601, + ProductName: 'Andalusia Cajun Rub Artisan', + SupplierID: 28, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 139.0, + UnitsInStock: 71, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-07-22'), + }, + { + ProductID: 602, + ProductName: 'Marrakesh Peanut Sauce Gold', + SupplierID: 18, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 186.95, + UnitsInStock: 80, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-12-19'), + }, + { + ProductID: 603, + ProductName: 'Verona Cold Brew Extra', + SupplierID: 23, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 212.95, + UnitsInStock: 88, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-07-10'), + }, + { + ProductID: 604, + ProductName: 'Istanbul Ricotta Traditional', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 135.0, + UnitsInStock: 137, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-04-28'), + }, + { + ProductID: 605, + ProductName: 'Dublin Halibut Steaks Premium', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 54.25, + UnitsInStock: 139, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-03-04'), + }, + { + ProductID: 606, + ProductName: 'Bavarian Bulgur Premium', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 35.0, + UnitsInStock: 0, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2013-12-27'), + }, + { + ProductID: 607, + ProductName: 'Ravenna Almond Biscotti Artisan', + SupplierID: 6, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 225.99, + UnitsInStock: 23, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-08-15'), + }, + { + ProductID: 608, + ProductName: 'Dublin Tortillas Extra', + SupplierID: 15, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 92.99, + UnitsInStock: 150, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2015-07-12'), + }, + { + ProductID: 609, + ProductName: 'Porto Ketchup Premium', + SupplierID: 18, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 181.25, + UnitsInStock: 64, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-03-13'), + }, + { + ProductID: 610, + ProductName: 'Nordsee Peanut Sauce Reserve', + SupplierID: 10, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 121.25, + UnitsInStock: 122, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-12-12'), + }, + { + ProductID: 611, + ProductName: 'Lima Polenta Deluxe', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 193.25, + UnitsInStock: 28, + UnitsOnOrder: 30, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2001-09-16'), + }, + { + ProductID: 612, + ProductName: 'Oslo Lemon Tarts Original', + SupplierID: 6, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 115.75, + UnitsInStock: 10, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2009-09-25'), + }, + { + ProductID: 613, + ProductName: 'Zurich Mustard Deluxe', + SupplierID: 16, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 191.95, + UnitsInStock: 73, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2005-03-03'), + }, + { + ProductID: 614, + ProductName: 'Valencia Wild Rice Reserve', + SupplierID: 1, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 102.95, + UnitsInStock: 128, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2008-09-21'), + }, + { + ProductID: 615, + ProductName: 'Gdansk Apple Juice Gold', + SupplierID: 21, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 45.99, + UnitsInStock: 14, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2010-07-06'), + }, + { + ProductID: 616, + ProductName: 'Toscana Brownie Bites Extra', + SupplierID: 28, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 198.25, + UnitsInStock: 75, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2009-06-13'), + }, + { + ProductID: 617, + ProductName: 'Riga Lemons Selection', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 192.0, + UnitsInStock: 132, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2014-01-21'), + }, + { + ProductID: 618, + ProductName: 'Bombay Baby Spinach Gold', + SupplierID: 18, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 174.5, + UnitsInStock: 7, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2005-09-17'), + }, + { + ProductID: 619, + ProductName: 'Cape Town Rooibos Tea Original', + SupplierID: 25, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 129.25, + UnitsInStock: 93, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-12-08'), + }, + { + ProductID: 620, + ProductName: 'Vilnius Seaweed Salad Selection', + SupplierID: 15, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 68.0, + UnitsInStock: 98, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2009-12-12'), + }, + { + ProductID: 621, + ProductName: 'Ghent Prosciutto Deluxe', + SupplierID: 11, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 46.95, + UnitsInStock: 77, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2000-10-02'), + }, + { + ProductID: 622, + ProductName: 'Escargot Butter Farmhouse', + SupplierID: 25, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 190.75, + UnitsInStock: 105, + UnitsOnOrder: 100, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2000-12-09'), + }, + { + ProductID: 623, + ProductName: 'Cascade Chorizo Gold', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 62.5, + UnitsInStock: 12, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-08-27'), + }, + { + ProductID: 624, + ProductName: 'Sicilian Bacon Strips Traditional', + SupplierID: 10, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 167.0, + UnitsInStock: 112, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2007-07-01'), + }, + { + ProductID: 625, + ProductName: 'Andalusia Lamb Chops Farmhouse', + SupplierID: 4, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 18.99, + UnitsInStock: 110, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-07-12'), + }, + { + ProductID: 626, + ProductName: 'Toulouse Kombucha Traditional', + SupplierID: 24, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 176.75, + UnitsInStock: 131, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-12-17'), + }, + { + ProductID: 627, + ProductName: 'Reykjavik Caramel Wafers Farmhouse', + SupplierID: 12, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 146.5, + UnitsInStock: 119, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2006-01-27'), + }, + { + ProductID: 628, + ProductName: 'Athens Pastrami Gold', + SupplierID: 7, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 178.75, + UnitsInStock: 126, + UnitsOnOrder: 60, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2007-04-17'), + }, + { + ProductID: 629, + ProductName: 'Cape Town Marinade Premium', + SupplierID: 4, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 159.5, + UnitsInStock: 5, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-11-28'), + }, + { + ProductID: 630, + ProductName: 'Genoa Licorice Drops Artisan', + SupplierID: 21, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 109.99, + UnitsInStock: 118, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2012-04-16'), + }, + { + ProductID: 631, + ProductName: 'Dublin Sausage Links Selection', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 174.75, + UnitsInStock: 32, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2001-02-11'), + }, + { + ProductID: 632, + ProductName: 'Bergen Praline Mix', + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 30.5, + UnitsInStock: 103, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2015-02-28'), + }, + { + ProductID: 633, + ProductName: 'Grandma Kellys Rye Bread Mix Premium', + SupplierID: 5, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 158.25, + UnitsInStock: 104, + UnitsOnOrder: 25, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2010-09-19'), + }, + { + ProductID: 634, + ProductName: 'Riga Marshmallows Original', + SupplierID: 26, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 44.99, + UnitsInStock: 50, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-12-19'), + }, + { + ProductID: 635, + ProductName: 'Toscana Shrimp Mix Traditional', + SupplierID: 18, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 155.95, + UnitsInStock: 60, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-08-18'), + }, + { + ProductID: 636, + ProductName: 'Aberdeen Baby Spinach Reserve', + SupplierID: 23, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 167.95, + UnitsInStock: 98, + UnitsOnOrder: 100, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2002-02-26'), + }, + { + ProductID: 637, + ProductName: 'Uncle Bobs Cherry Tomatoes Premium', + SupplierID: 20, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 17.5, + UnitsInStock: 121, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2004-11-14'), + }, + { + ProductID: 638, + ProductName: 'Alpen Pilsner', + SupplierID: 3, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 197.5, + UnitsInStock: 104, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2018-09-11'), + }, + { + ProductID: 639, + ProductName: 'Malaga Rye Bread Mix Artisan', + SupplierID: 1, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 234.5, + UnitsInStock: 14, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-05-04'), + }, + { + ProductID: 640, + ProductName: 'Riga Sardines Gold', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 110.95, + UnitsInStock: 40, + UnitsOnOrder: 60, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2011-07-21'), + }, + { + ProductID: 641, + ProductName: 'Shanghai Caramel Wafers Traditional', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 40.99, + UnitsInStock: 28, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2018-10-23'), + }, + { + ProductID: 642, + ProductName: 'Riga Butter Classic', + SupplierID: 26, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 49.99, + UnitsInStock: 72, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2015-01-01'), + }, + { + ProductID: 643, + ProductName: 'Genoa Provolone Farmhouse', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 129.5, + UnitsInStock: 129, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-09-10'), + }, + { + ProductID: 644, + ProductName: 'Bordeaux Curry Paste Classic', + SupplierID: 26, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 212.75, + UnitsInStock: 16, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-10-01'), + }, + { + ProductID: 645, + ProductName: 'Aberdeen Curry Paste Traditional', + SupplierID: 7, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 221.5, + UnitsInStock: 21, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-01-05'), + }, + { + ProductID: 646, + ProductName: 'Pavlova Marshmallows Extra', + SupplierID: 12, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 104.25, + UnitsInStock: 75, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-08-13'), + }, + { + ProductID: 647, + ProductName: 'Naples Sriracha Gold', + SupplierID: 21, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 117.25, + UnitsInStock: 29, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2013-04-21'), + }, + { + ProductID: 648, + ProductName: 'Valencia Rye Bread Mix Reserve', + SupplierID: 13, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 199.5, + UnitsInStock: 90, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2014-05-15'), + }, + { + ProductID: 649, + ProductName: 'Porto Coconut Bars Farmhouse', + SupplierID: 28, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 111.95, + UnitsInStock: 41, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2000-12-06'), + }, + { + ProductID: 650, + ProductName: 'Krakow Hazelnut Cream Selection', + SupplierID: 15, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 122.75, + UnitsInStock: 52, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2019-11-18'), + }, + { + ProductID: 651, + ProductName: 'Bavarian Rum Balls Premium', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 50.95, + UnitsInStock: 114, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-11-05'), + }, + { + ProductID: 652, + ProductName: 'Riga Almond Biscotti Farmhouse', + SupplierID: 1, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 234.75, + UnitsInStock: 96, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-04-16'), + }, + { + ProductID: 653, + ProductName: 'Bratislava Elderflower Cordial Extra', + SupplierID: 25, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 63.0, + UnitsInStock: 82, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-02-14'), + }, + { + ProductID: 654, + ProductName: 'Toscana Muesli Selection', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 204.25, + UnitsInStock: 1, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-02-11'), + }, + { + ProductID: 655, + ProductName: 'Athens Rice Crackers Reserve', + SupplierID: 14, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 162.99, + UnitsInStock: 19, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-05-21'), + }, + { + ProductID: 656, + ProductName: 'Vienna Rabbit Stew Farmhouse', + SupplierID: 1, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 182.99, + UnitsInStock: 142, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2014-11-04'), + }, + { + ProductID: 657, + ProductName: 'Basel Chili Sauce Selection', + SupplierID: 21, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 63.75, + UnitsInStock: 88, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2010-04-24'), + }, + { + ProductID: 658, + ProductName: 'Zurich Sardines Traditional', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 90.99, + UnitsInStock: 77, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-12-26'), + }, + { + ProductID: 659, + ProductName: 'Rotterdam Kefir Original', + SupplierID: 19, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 166.75, + UnitsInStock: 91, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2007-09-21'), + }, + { + ProductID: 660, + ProductName: 'Malaga Iced Tea Original', + SupplierID: 13, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 199.75, + UnitsInStock: 123, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-01-07'), + }, + { + ProductID: 661, + ProductName: 'Verona Chai Blend', + SupplierID: 20, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 51.5, + UnitsInStock: 90, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-10-12'), + }, + { + ProductID: 662, + ProductName: 'Helsinki Dried Apricots Classic', + SupplierID: 11, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 146.5, + UnitsInStock: 136, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-02-17'), + }, + { + ProductID: 663, + ProductName: 'Brisbane Kefir Farmhouse', + SupplierID: 1, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 73.95, + UnitsInStock: 99, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2003-01-06'), + }, + { + ProductID: 664, + ProductName: 'Genoa Polenta Original', + SupplierID: 2, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 138.75, + UnitsInStock: 106, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-02-12'), + }, + { + ProductID: 665, + ProductName: 'Riga Curry Paste Extra', + SupplierID: 25, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 52.75, + UnitsInStock: 84, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2005-08-27'), + }, + { + ProductID: 666, + ProductName: 'Pavlova Cajun Rub Traditional', + SupplierID: 20, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 220.5, + UnitsInStock: 27, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2001-03-23'), + }, + { + ProductID: 667, + ProductName: 'Chef Antons Garlic Puree Artisan', + SupplierID: 1, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 171.25, + UnitsInStock: 4, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-07-04'), + }, + { + ProductID: 668, + ProductName: 'Cascade Shortbread Premium', + SupplierID: 19, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 171.75, + UnitsInStock: 98, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2016-06-05'), + }, + { + ProductID: 669, + ProductName: 'Bratislava Mayonnaise Extra', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 200.95, + UnitsInStock: 68, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2009-06-15'), + }, + { + ProductID: 670, + ProductName: 'Ghent Eel Fillets Original', + SupplierID: 12, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 156.99, + UnitsInStock: 34, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2020-01-09'), + }, + { + ProductID: 671, + ProductName: 'Chef Antons Shortbread Farmhouse', + SupplierID: 10, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 147.25, + UnitsInStock: 6, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2014-02-20'), + }, + { + ProductID: 672, + ProductName: 'Lisbon Cheddar Blocks Classic', + SupplierID: 8, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 55.75, + UnitsInStock: 39, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2005-03-28'), + }, + { + ProductID: 673, + ProductName: 'Escargot Pilsner Premium', + SupplierID: 18, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 54.95, + UnitsInStock: 116, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2009-06-21'), + }, + { + ProductID: 674, + ProductName: 'Vilnius Caviar Reserve', + SupplierID: 14, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 136.0, + UnitsInStock: 112, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2009-09-09'), + }, + { + ProductID: 675, + ProductName: 'Antwerp Horseradish Deluxe', + SupplierID: 16, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 39.95, + UnitsInStock: 5, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2010-05-07'), + }, + { + ProductID: 676, + ProductName: 'Kyoto Cranberry Relish Traditional', + SupplierID: 27, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 48.25, + UnitsInStock: 30, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-09-23'), + }, + { + ProductID: 677, + ProductName: 'Granada Bulgur Traditional', + SupplierID: 7, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 16.95, + UnitsInStock: 124, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-01-24'), + }, + { + ProductID: 678, + ProductName: 'Riga Nougat Bars Selection', + SupplierID: 5, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 152.75, + UnitsInStock: 4, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2000-07-03'), + }, + { + ProductID: 679, + ProductName: 'Pavlova Almond Biscotti Artisan', + SupplierID: 16, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 236.25, + UnitsInStock: 117, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-03-23'), + }, + { + ProductID: 680, + ProductName: 'Granada Tahini Selection', + SupplierID: 25, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 207.5, + UnitsInStock: 30, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2011-01-22'), + }, + { + ProductID: 681, + ProductName: 'Basel Trout Fillets Artisan', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 112.25, + UnitsInStock: 64, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2008-02-15'), + }, + { + ProductID: 682, + ProductName: 'Zurich Rabbit Stew Farmhouse', + SupplierID: 12, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 217.95, + UnitsInStock: 24, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2008-05-10'), + }, + { + ProductID: 683, + ProductName: 'Sicilian Salami Deluxe', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 170.95, + UnitsInStock: 93, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2001-05-10'), + }, + { + ProductID: 684, + ProductName: 'Antwerp Macaroons Artisan', + SupplierID: 6, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 31.75, + UnitsInStock: 95, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2020-12-26'), + }, + { + ProductID: 685, + ProductName: 'Krakow Venison Steaks Artisan', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 118.75, + UnitsInStock: 89, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-09-04'), + }, + { + ProductID: 686, + ProductName: 'Bucharest Ale', + SupplierID: 27, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 161.5, + UnitsInStock: 109, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2019-04-13'), + }, + { + ProductID: 687, + ProductName: 'Cape Town Red Peppers Extra', + SupplierID: 7, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 87.25, + UnitsInStock: 107, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2003-12-15'), + }, + { + ProductID: 688, + ProductName: 'Sofia Brownie Bites Artisan', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 12.0, + UnitsInStock: 29, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2000-11-25'), + }, + { + ProductID: 689, + ProductName: 'Malaga Caramel Wafers Deluxe', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 36.25, + UnitsInStock: 47, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-06-17'), + }, + { + ProductID: 690, + ProductName: 'Provence Whipping Cream Reserve', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 86.5, + UnitsInStock: 91, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-12-05'), + }, + { + ProductID: 691, + ProductName: 'Vienna Asparagus Spears Traditional', + SupplierID: 10, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 208.25, + UnitsInStock: 70, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2006-11-04'), + }, + { + ProductID: 692, + ProductName: 'Reykjavik Squid Rings Premium', + SupplierID: 9, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 46.95, + UnitsInStock: 59, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2014-04-07'), + }, + { + ProductID: 693, + ProductName: 'Provence Whipping Cream Deluxe', + SupplierID: 6, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 167.0, + UnitsInStock: 10, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2011-11-22'), + }, + { + ProductID: 694, + ProductName: 'Ghent Coconut Bars Classic', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 177.5, + UnitsInStock: 4, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2005-12-17'), + }, + { + ProductID: 695, + ProductName: 'Ljubljana Buckwheat Premium', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 32.75, + UnitsInStock: 75, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2003-09-27'), + }, + { + ProductID: 696, + ProductName: 'Kyoto Herring Fillets Selection', + SupplierID: 14, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 184.95, + UnitsInStock: 14, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2007-01-12'), + }, + { + ProductID: 697, + ProductName: 'Copenhagen Corned Beef Reserve', + SupplierID: 4, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 25.5, + UnitsInStock: 42, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2001-02-11'), + }, + { + ProductID: 698, + ProductName: 'Zagreb Brie Wheel Reserve', + SupplierID: 6, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 104.25, + UnitsInStock: 83, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2019-03-02'), + }, + { + ProductID: 699, + ProductName: 'Pavlova Semolina Original', + SupplierID: 23, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 98.25, + UnitsInStock: 135, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2020-08-10'), + }, + { + ProductID: 700, + ProductName: 'Toulouse Marshmallows Selection', + SupplierID: 15, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 177.95, + UnitsInStock: 10, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2017-02-15'), + }, + { + ProductID: 701, + ProductName: 'Verona Meatballs Reserve', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 50.0, + UnitsInStock: 38, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2012-11-23'), + }, + { + ProductID: 702, + ProductName: 'Odessa Chai Blend Farmhouse', + SupplierID: 19, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 70.75, + UnitsInStock: 4, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-09-14'), + }, + { + ProductID: 703, + ProductName: 'Montreal Cajun Rub Farmhouse', + SupplierID: 9, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 173.95, + UnitsInStock: 8, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-03-18'), + }, + { + ProductID: 704, + ProductName: 'Andalusia Emmental Artisan', + SupplierID: 3, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 114.25, + UnitsInStock: 102, + UnitsOnOrder: 60, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2014-03-26'), + }, + { + ProductID: 705, + ProductName: 'Reykjavik Sea Bass Extra', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 13.95, + UnitsInStock: 137, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2013-01-21'), + }, + { + ProductID: 706, + ProductName: 'Bratislava Pilsner Premium', + SupplierID: 17, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 24.95, + UnitsInStock: 133, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2005-03-04'), + }, + { + ProductID: 707, + ProductName: 'Sicilian Sponge Cake Artisan', + SupplierID: 16, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 178.0, + UnitsInStock: 134, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2007-08-23'), + }, + { + ProductID: 708, + ProductName: 'Toulouse Portobello Mushrooms Gold', + SupplierID: 12, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 204.99, + UnitsInStock: 15, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2000-11-02'), + }, + { + ProductID: 709, + ProductName: 'Vienna Sponge Cake Extra', + SupplierID: 12, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 87.75, + UnitsInStock: 130, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2008-10-23'), + }, + { + ProductID: 710, + ProductName: 'Louisiana Dried Apples Extra', + SupplierID: 5, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 150.25, + UnitsInStock: 57, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2014-04-05'), + }, + { + ProductID: 711, + ProductName: 'Uncle Bobs Hazelnut Cream', + SupplierID: 22, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 87.99, + UnitsInStock: 57, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2005-09-08'), + }, + { + ProductID: 712, + ProductName: 'Cascade Fudge Squares Artisan', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 56.5, + UnitsInStock: 13, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2018-02-01'), + }, + { + ProductID: 713, + ProductName: 'Basel Duck Confit Selection', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 187.0, + UnitsInStock: 49, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2018-11-17'), + }, + { + ProductID: 714, + ProductName: 'Ghent Buckwheat Reserve', + SupplierID: 13, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 43.75, + UnitsInStock: 126, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2004-05-08'), + }, + { + ProductID: 715, + ProductName: 'Lisbon Marinade Deluxe', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 114.25, + UnitsInStock: 136, + UnitsOnOrder: 100, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2001-09-16'), + }, + { + ProductID: 716, + ProductName: 'Salzburg Buttermilk Traditional', + SupplierID: 5, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 12.5, + UnitsInStock: 114, + UnitsOnOrder: 20, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2008-10-08'), + }, + { + ProductID: 717, + ProductName: 'Gdansk Sesame Crunch Extra', + SupplierID: 27, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 114.95, + UnitsInStock: 93, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-03-25'), + }, + { + ProductID: 718, + ProductName: 'Genoa Semolina Selection', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 19.5, + UnitsInStock: 92, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2001-12-19'), + }, + { + ProductID: 719, + ProductName: 'Lisbon Yoghurt Gold', + SupplierID: 28, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 94.25, + UnitsInStock: 20, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2016-10-22'), + }, + { + ProductID: 720, + ProductName: 'Sofia Green Beans Selection', + SupplierID: 10, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 110.5, + UnitsInStock: 57, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2007-12-04'), + }, + { + ProductID: 721, + ProductName: 'Zurich Smoked Ham Extra', + SupplierID: 7, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 53.75, + UnitsInStock: 44, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2011-01-12'), + }, + { + ProductID: 722, + ProductName: 'Malaga Wild Rice Farmhouse', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 137.75, + UnitsInStock: 83, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2019-05-14'), + }, + { + ProductID: 723, + ProductName: 'Seville Ginger Root Original', + SupplierID: 22, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 47.75, + UnitsInStock: 93, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-12-04'), + }, + { + ProductID: 724, + ProductName: 'Bucharest Spelt Flour Premium', + SupplierID: 10, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 117.0, + UnitsInStock: 68, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-02-18'), + }, + { + ProductID: 725, + ProductName: 'Valencia Couscous Traditional', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 135.0, + UnitsInStock: 125, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2002-10-04'), + }, + { + ProductID: 726, + ProductName: 'Genoa Curry Paste Selection', + SupplierID: 6, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 153.95, + UnitsInStock: 33, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-06-21'), + }, + { + ProductID: 727, + ProductName: 'Riga Beef Jerky Extra', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 9.0, + UnitsInStock: 72, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2012-06-10'), + }, + { + ProductID: 728, + ProductName: 'Andalusia Sweet Corn Original', + SupplierID: 8, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 233.5, + UnitsInStock: 67, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2020-09-06'), + }, + { + ProductID: 729, + ProductName: 'Escargot Apple Juice Selection', + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 55.0, + UnitsInStock: 55, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2001-04-04'), + }, + { + ProductID: 730, + ProductName: 'Valencia Creme Fraiche Classic', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 85.25, + UnitsInStock: 8, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-07-06'), + }, + { + ProductID: 731, + ProductName: 'Bruges Sriracha Original', + SupplierID: 22, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 119.75, + UnitsInStock: 5, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2012-07-26'), + }, + { + ProductID: 732, + ProductName: 'Copenhagen Bacon Strips Reserve', + SupplierID: 24, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 157.0, + UnitsInStock: 147, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-07-20'), + }, + { + ProductID: 733, + ProductName: 'Cascade Sun Dried Tomatoes Classic', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 49.75, + UnitsInStock: 8, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-06-09'), + }, + { + ProductID: 734, + ProductName: 'Santiago Corned Beef Extra', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 134.99, + UnitsInStock: 84, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-08-03'), + }, + { + ProductID: 735, + ProductName: 'Naples Dried Apricots Original', + SupplierID: 26, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 233.5, + UnitsInStock: 47, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2006-11-24'), + }, + { + ProductID: 736, + ProductName: 'Bruges Cherry Tomatoes Selection', + SupplierID: 13, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 238.0, + UnitsInStock: 110, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2014-08-04'), + }, + { + ProductID: 737, + ProductName: 'Krakow Balsamic Vinegar Artisan', + SupplierID: 28, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 3.25, + UnitsInStock: 52, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2011-01-03'), + }, + { + ProductID: 738, + ProductName: 'Copenhagen Pesto Farmhouse', + SupplierID: 15, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 207.0, + UnitsInStock: 73, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-09-10'), + }, + { + ProductID: 739, + ProductName: 'Vilnius Amaranth Deluxe', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 156.5, + UnitsInStock: 44, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-09-03'), + }, + { + ProductID: 740, + ProductName: 'Lisbon Sausage Links Reserve', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 17.75, + UnitsInStock: 64, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2010-10-07'), + }, + { + ProductID: 741, + ProductName: 'Salzburg Feta', + SupplierID: 17, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 62.99, + UnitsInStock: 8, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-12-19'), + }, + { + ProductID: 742, + ProductName: 'Andalusia Brownie Bites Classic', + SupplierID: 15, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 207.25, + UnitsInStock: 150, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2002-03-07'), + }, + { + ProductID: 743, + ProductName: 'Santiago Wasabi Paste Deluxe', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 235.75, + UnitsInStock: 141, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-12-25'), + }, + { + ProductID: 744, + ProductName: 'Ljubljana Muesli Artisan', + SupplierID: 16, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 22.0, + UnitsInStock: 18, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-08-26'), + }, + { + ProductID: 745, + ProductName: 'Rotterdam Quail Breasts', + SupplierID: 15, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 174.0, + UnitsInStock: 124, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2011-08-21'), + }, + { + ProductID: 746, + ProductName: 'Rotterdam Creme Fraiche Reserve', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 84.99, + UnitsInStock: 39, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2000-09-09'), + }, + { + ProductID: 747, + ProductName: 'Bucharest Dried Apples Artisan', + SupplierID: 22, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 105.25, + UnitsInStock: 45, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2007-06-07'), + }, + { + ProductID: 748, + ProductName: 'Montreal Shrimp Mix Selection', + SupplierID: 4, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 113.0, + UnitsInStock: 138, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2007-04-11'), + }, + { + ProductID: 749, + ProductName: 'Graz Portobello Mushrooms Classic', + SupplierID: 1, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 222.5, + UnitsInStock: 83, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-03-13'), + }, + { + ProductID: 750, + ProductName: 'Bavarian Blue Mussels Artisan', + SupplierID: 16, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 32.0, + UnitsInStock: 150, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2004-08-19'), + }, + { + ProductID: 751, + ProductName: 'Copenhagen Tahini Deluxe', + SupplierID: 6, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 235.25, + UnitsInStock: 135, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-07-22'), + }, + { + ProductID: 752, + ProductName: 'Istanbul Rib Roast Extra', + SupplierID: 10, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 16.0, + UnitsInStock: 109, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2019-03-12'), + }, + { + ProductID: 753, + ProductName: 'Cape Town Barbecue Sauce Reserve', + SupplierID: 23, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 87.5, + UnitsInStock: 147, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-10-12'), + }, + { + ProductID: 754, + ProductName: 'Odessa Dried Apricots Traditional', + SupplierID: 27, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 79.25, + UnitsInStock: 40, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2000-02-12'), + }, + { + ProductID: 755, + ProductName: 'Aberdeen Sponge Cake Classic', + SupplierID: 22, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 167.99, + UnitsInStock: 129, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2017-02-15'), + }, + { + ProductID: 756, + ProductName: 'Bratislava Cornmeal Original', + SupplierID: 1, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 35.0, + UnitsInStock: 56, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-02-09'), + }, + { + ProductID: 757, + ProductName: 'Granada Asparagus Spears Selection', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 22.0, + UnitsInStock: 97, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2016-10-07'), + }, + { + ProductID: 758, + ProductName: 'Ghent Caviar Reserve', + SupplierID: 10, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 79.25, + UnitsInStock: 38, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2020-06-11'), + }, + { + ProductID: 759, + ProductName: 'Gustafs Sardines Selection', + SupplierID: 5, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 235.5, + UnitsInStock: 96, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-11-01'), + }, + { + ProductID: 760, + ProductName: 'Krakow Lemon Tarts Selection', + SupplierID: 6, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 163.75, + UnitsInStock: 69, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-09-02'), + }, + { + ProductID: 761, + ProductName: 'Krakow Lobster Tails Reserve', + SupplierID: 19, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 11.25, + UnitsInStock: 111, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2017-09-05'), + }, + { + ProductID: 762, + ProductName: 'Riga Wild Rice Original', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 25.95, + UnitsInStock: 142, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-12-09'), + }, + { + ProductID: 763, + ProductName: 'Gdansk Roasted Chestnuts Selection', + SupplierID: 16, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 138.0, + UnitsInStock: 51, + UnitsOnOrder: 30, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2000-12-28'), + }, + { + ProductID: 764, + ProductName: 'Antwerp Mango Nectar Deluxe', + SupplierID: 4, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 213.0, + UnitsInStock: 125, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-02-09'), + }, + { + ProductID: 765, + ProductName: 'Riga Egg Noodles Deluxe', + SupplierID: 15, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 85.25, + UnitsInStock: 103, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2016-12-13'), + }, + { + ProductID: 766, + ProductName: 'Vienna Bratwurst Extra', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 60.25, + UnitsInStock: 90, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2003-07-02'), + }, + { + ProductID: 767, + ProductName: 'Cairo Camembert Gold', + SupplierID: 21, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 144.75, + UnitsInStock: 36, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2003-02-04'), + }, + { + ProductID: 768, + ProductName: 'Bordeaux Portobello Mushrooms Deluxe', + SupplierID: 15, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 14.95, + UnitsInStock: 85, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-02-28'), + }, + { + ProductID: 769, + ProductName: 'Zagreb Trout Fillets Reserve', + SupplierID: 18, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 92.95, + UnitsInStock: 142, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2008-04-06'), + }, + { + ProductID: 770, + ProductName: 'Nantes Apple Chutney Extra', + SupplierID: 28, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 100.99, + UnitsInStock: 147, + UnitsOnOrder: 25, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2002-02-18'), + }, + { + ProductID: 771, + ProductName: 'Naples Pork Loin', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 216.0, + UnitsInStock: 19, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-04-18'), + }, + { + ProductID: 772, + ProductName: 'Alpen Cold Brew Farmhouse', + SupplierID: 13, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 94.0, + UnitsInStock: 11, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2020-07-25'), + }, + { + ProductID: 773, + ProductName: 'Naples Almond Biscotti Selection', + SupplierID: 27, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 36.5, + UnitsInStock: 59, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2000-04-20'), + }, + { + ProductID: 774, + ProductName: 'Valencia Iced Tea Extra', + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 13.99, + UnitsInStock: 28, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2019-08-27'), + }, + { + ProductID: 775, + ProductName: 'Cascade Harissa', + SupplierID: 13, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 229.25, + UnitsInStock: 6, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-05-06'), + }, + { + ProductID: 776, + ProductName: 'Nordsee Curry Paste Gold', + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 85.5, + UnitsInStock: 142, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-04-28'), + }, + { + ProductID: 777, + ProductName: 'Zurich Trout Fillets Reserve', + SupplierID: 19, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 121.99, + UnitsInStock: 51, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2005-12-05'), + }, + { + ProductID: 778, + ProductName: 'Vienna Chicken Breast Deluxe', + SupplierID: 8, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 63.5, + UnitsInStock: 123, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2008-08-03'), + }, + { + ProductID: 779, + ProductName: 'Bavarian Leeks Gold', + SupplierID: 2, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 225.75, + UnitsInStock: 33, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-09-02'), + }, + { + ProductID: 780, + ProductName: 'Cairo Squid Rings Deluxe', + SupplierID: 14, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 74.5, + UnitsInStock: 33, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-05-15'), + }, + { + ProductID: 781, + ProductName: 'Basel Oysters Selection', + SupplierID: 12, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 208.75, + UnitsInStock: 47, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2016-02-23'), + }, + { + ProductID: 782, + ProductName: 'Valencia Egg Noodles Artisan', + SupplierID: 13, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 109.75, + UnitsInStock: 57, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2016-01-10'), + }, + { + ProductID: 783, + ProductName: 'Louisiana Pastrami Selection', + SupplierID: 1, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 144.95, + UnitsInStock: 37, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-05-08'), + }, + { + ProductID: 784, + ProductName: 'Alpen Eel Fillets Gold', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 151.99, + UnitsInStock: 114, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-12-09'), + }, + { + ProductID: 785, + ProductName: 'Lisbon Pilsner', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 13.0, + UnitsInStock: 128, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2019-10-22'), + }, + { + ProductID: 786, + ProductName: 'Ghent Rib Roast Selection', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 107.75, + UnitsInStock: 99, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-09-04'), + }, + { + ProductID: 787, + ProductName: 'Copenhagen Beef Jerky Gold', + SupplierID: 17, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 202.25, + UnitsInStock: 88, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2016-12-13'), + }, + { + ProductID: 788, + ProductName: 'Sicilian Manchego Reserve', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 186.25, + UnitsInStock: 111, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2002-06-28'), + }, + { + ProductID: 789, + ProductName: 'Verona Lamb Chops Farmhouse', + SupplierID: 1, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 90.5, + UnitsInStock: 113, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2010-08-13'), + }, + { + ProductID: 790, + ProductName: 'Reykjavik Asparagus Spears Deluxe', + SupplierID: 2, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 47.75, + UnitsInStock: 75, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2011-11-24'), + }, + { + ProductID: 791, + ProductName: 'Dublin Sun Dried Tomatoes Original', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 201.5, + UnitsInStock: 118, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-05-27'), + }, + { + ProductID: 792, + ProductName: 'Naples Smoked Ham Extra', + SupplierID: 12, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 35.5, + UnitsInStock: 76, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-09-25'), + }, + { + ProductID: 793, + ProductName: 'Alpen Crayfish Farmhouse', + SupplierID: 5, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 88.0, + UnitsInStock: 37, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-10-21'), + }, + { + ProductID: 794, + ProductName: 'Uncle Bobs Fennel Bulbs Gold', + SupplierID: 16, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 25.95, + UnitsInStock: 66, + UnitsOnOrder: 60, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2007-09-05'), + }, + { + ProductID: 795, + ProductName: 'Copenhagen Harissa Traditional', + SupplierID: 19, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 123.0, + UnitsInStock: 64, + UnitsOnOrder: 25, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2011-04-10'), + }, + { + ProductID: 796, + ProductName: 'Vienna Sourdough Mix Gold', + SupplierID: 19, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 118.75, + UnitsInStock: 138, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2007-01-08'), + }, + { + ProductID: 797, + ProductName: 'Sofia Nougat Bars Traditional', + SupplierID: 16, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 119.0, + UnitsInStock: 150, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-07-09'), + }, + { + ProductID: 798, + ProductName: 'Nantes Plaice Fillets Farmhouse', + SupplierID: 11, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 47.25, + UnitsInStock: 105, + UnitsOnOrder: 50, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2001-03-22'), + }, + { + ProductID: 799, + ProductName: 'Brisbane Parmesan Shavings Extra', + SupplierID: 16, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 191.0, + UnitsInStock: 100, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2014-08-02'), + }, + { + ProductID: 800, + ProductName: 'Utrecht Sponge Cake Farmhouse', + SupplierID: 27, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 11.0, + UnitsInStock: 117, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-05-20'), + }, + { + ProductID: 801, + ProductName: 'Tokyo Polenta Farmhouse', + SupplierID: 9, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 37.99, + UnitsInStock: 60, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2004-04-27'), + }, + { + ProductID: 802, + ProductName: 'Cairo Fudge Squares Original', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 140.5, + UnitsInStock: 115, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2015-01-18'), + }, + { + ProductID: 803, + ProductName: 'Lisbon Stollen', + SupplierID: 12, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 13.0, + UnitsInStock: 124, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2017-03-24'), + }, + { + ProductID: 804, + ProductName: 'Bergen Chicken Breast Reserve', + SupplierID: 25, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 179.0, + UnitsInStock: 19, + UnitsOnOrder: 10, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2013-10-13'), + }, + { + ProductID: 805, + ProductName: 'Salzburg Sponge Cake Original', + SupplierID: 15, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 63.99, + UnitsInStock: 0, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2000-08-15'), + }, + { + ProductID: 806, + ProductName: 'Kyoto Whole Wheat Flour Farmhouse', + SupplierID: 23, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 124.95, + UnitsInStock: 130, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2020-06-15'), + }, + { + ProductID: 807, + ProductName: 'Reykjavik Lager', + SupplierID: 5, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 204.95, + UnitsInStock: 25, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-09-20'), + }, + { + ProductID: 808, + ProductName: 'Dublin Hazelnut Cream Reserve', + SupplierID: 11, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 170.75, + UnitsInStock: 44, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2010-03-09'), + }, + { + ProductID: 809, + ProductName: 'Ravenna Turkey Roast Extra', + SupplierID: 6, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 15.95, + UnitsInStock: 48, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-06-02'), + }, + { + ProductID: 810, + ProductName: 'Odessa Egg Noodles Extra', + SupplierID: 5, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 51.5, + UnitsInStock: 20, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2007-11-13'), + }, + { + ProductID: 811, + ProductName: 'Toscana Quail Breasts Selection', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 181.75, + UnitsInStock: 43, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-07-24'), + }, + { + ProductID: 812, + ProductName: 'Basel Mint Creams Deluxe', + SupplierID: 1, + CategoryID: 3, + QuantityPerUnit: '20 - 200 g bags', + UnitPrice: 196.99, + UnitsInStock: 128, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2013-12-20'), + }, + { + ProductID: 813, + ProductName: 'Ljubljana Cabernet Reserve', + SupplierID: 22, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 22.5, + UnitsInStock: 53, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-02-01'), + }, + { + ProductID: 814, + ProductName: 'Antwerp Rabbit Stew Original', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 236.0, + UnitsInStock: 109, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2007-02-20'), + }, + { + ProductID: 815, + ProductName: 'Odessa Herring Fillets Extra', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 215.0, + UnitsInStock: 97, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2008-06-26'), + }, + { + ProductID: 816, + ProductName: 'Bratislava Wasabi Paste Classic', + SupplierID: 15, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 177.75, + UnitsInStock: 134, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-09-22'), + }, + { + ProductID: 817, + ProductName: 'Naples Duck Confit Selection', + SupplierID: 20, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 28.75, + UnitsInStock: 16, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2017-05-27'), + }, + { + ProductID: 818, + ProductName: 'Tokyo Mackerel Gold', + SupplierID: 16, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 198.5, + UnitsInStock: 107, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2001-03-09'), + }, + { + ProductID: 819, + ProductName: 'Cape Town Truffle Oil Reserve', + SupplierID: 18, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 86.5, + UnitsInStock: 96, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-03-05'), + }, + { + ProductID: 820, + ProductName: 'Vienna Sausage Links Farmhouse', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 9.5, + UnitsInStock: 100, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-06-08'), + }, + { + ProductID: 821, + ProductName: 'Gdansk Smoked Salmon Deluxe', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 210.0, + UnitsInStock: 37, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-07-19'), + }, + { + ProductID: 822, + ProductName: 'Tallinn Garlic Puree Extra', + SupplierID: 9, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 153.75, + UnitsInStock: 116, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2007-07-27'), + }, + { + ProductID: 823, + ProductName: 'Seville Butter Cookies Classic', + SupplierID: 5, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 142.75, + UnitsInStock: 69, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2016-02-01'), + }, + { + ProductID: 824, + ProductName: 'Verona Pomegranates Traditional', + SupplierID: 7, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 40.95, + UnitsInStock: 48, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-07-06'), + }, + { + ProductID: 825, + ProductName: 'Granada Red Peppers Artisan', + SupplierID: 7, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 218.95, + UnitsInStock: 127, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-11-09'), + }, + { + ProductID: 826, + ProductName: 'Bavarian Whipping Cream Deluxe', + SupplierID: 28, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 139.5, + UnitsInStock: 7, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2019-07-16'), + }, + { + ProductID: 827, + ProductName: 'Santiago Butter Deluxe', + SupplierID: 10, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 119.0, + UnitsInStock: 70, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-02-28'), + }, + { + ProductID: 828, + ProductName: 'Vienna Meatballs Reserve', + SupplierID: 16, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 117.75, + UnitsInStock: 138, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-08-12'), + }, + { + ProductID: 829, + ProductName: 'Oslo Honey Cakes Premium', + SupplierID: 9, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 184.5, + UnitsInStock: 51, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2016-12-24'), + }, + { + ProductID: 830, + ProductName: 'Utrecht Crayfish Extra', + SupplierID: 4, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 30.0, + UnitsInStock: 64, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2002-05-02'), + }, + { + ProductID: 831, + ProductName: 'Bratislava Pomegranates Deluxe', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 152.75, + UnitsInStock: 6, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-07-17'), + }, + { + ProductID: 832, + ProductName: 'Istanbul Sriracha Deluxe', + SupplierID: 20, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 131.5, + UnitsInStock: 46, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2004-03-15'), + }, + { + ProductID: 833, + ProductName: 'Toulouse Cola Deluxe', + SupplierID: 8, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 193.5, + UnitsInStock: 131, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-12-14'), + }, + { + ProductID: 834, + ProductName: 'Istanbul Balsamic Vinegar Reserve', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 69.5, + UnitsInStock: 147, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-03-28'), + }, + { + ProductID: 835, + ProductName: 'Verona Shallots', + SupplierID: 6, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 145.75, + UnitsInStock: 25, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2010-12-07'), + }, + { + ProductID: 836, + ProductName: 'Odessa Quark Extra', + SupplierID: 23, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 184.0, + UnitsInStock: 55, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2005-07-19'), + }, + { + ProductID: 837, + ProductName: 'Lima Balsamic Vinegar Traditional', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 187.5, + UnitsInStock: 57, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2012-01-10'), + }, + { + ProductID: 838, + ProductName: 'Kyoto Nougat Bars', + SupplierID: 15, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 209.5, + UnitsInStock: 26, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-01-14'), + }, + { + ProductID: 839, + ProductName: 'Alpen Seaweed Salad Classic', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 125.25, + UnitsInStock: 61, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2016-04-28'), + }, + { + ProductID: 840, + ProductName: 'Zagreb Goose Liver Traditional', + SupplierID: 9, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 69.99, + UnitsInStock: 62, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2012-09-05'), + }, + { + ProductID: 841, + ProductName: 'Highland Cream Cheese Premium', + SupplierID: 20, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 131.75, + UnitsInStock: 143, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2005-10-13'), + }, + { + ProductID: 842, + ProductName: 'Krakow Sardines Reserve', + SupplierID: 17, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 213.99, + UnitsInStock: 118, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-04-22'), + }, + { + ProductID: 843, + ProductName: 'Porto Octopus Selection', + SupplierID: 11, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 101.5, + UnitsInStock: 80, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2012-05-15'), + }, + { + ProductID: 844, + ProductName: 'Cape Town Pesto Original', + SupplierID: 22, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 71.99, + UnitsInStock: 1, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2003-07-20'), + }, + { + ProductID: 845, + ProductName: 'Bergen Fudge Squares Gold', + SupplierID: 1, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 219.5, + UnitsInStock: 97, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-09-28'), + }, + { + ProductID: 846, + ProductName: 'Marrakesh Olive Oil Premium', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 132.99, + UnitsInStock: 132, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2019-02-08'), + }, + { + ProductID: 847, + ProductName: 'Salzburg Rose Wine', + SupplierID: 28, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 134.25, + UnitsInStock: 148, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2001-08-01'), + }, + { + ProductID: 848, + ProductName: 'Krakow Couscous Deluxe', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 16.0, + UnitsInStock: 137, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-02-12'), + }, + { + ProductID: 849, + ProductName: 'Tallinn Mozzarella Selection', + SupplierID: 3, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 210.99, + UnitsInStock: 126, + UnitsOnOrder: 60, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2018-07-01'), + }, + { + ProductID: 850, + ProductName: 'Genoa Sardines', + SupplierID: 27, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 12.5, + UnitsInStock: 24, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2006-05-03'), + }, + { + ProductID: 851, + ProductName: 'Nordsee Wasabi Paste Traditional', + SupplierID: 20, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 123.0, + UnitsInStock: 135, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2010-10-13'), + }, + { + ProductID: 852, + ProductName: 'Granada Manchego Extra', + SupplierID: 17, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 237.0, + UnitsInStock: 6, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2001-02-20'), + }, + { + ProductID: 853, + ProductName: 'Nordsee Marinade Deluxe', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 196.25, + UnitsInStock: 122, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2018-12-24'), + }, + { + ProductID: 854, + ProductName: 'Bordeaux Sourdough Mix Reserve', + SupplierID: 6, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 128.0, + UnitsInStock: 28, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-01-28'), + }, + { + ProductID: 855, + ProductName: 'Gdansk Licorice Drops', + SupplierID: 17, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 179.99, + UnitsInStock: 150, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2000-02-11'), + }, + { + ProductID: 856, + ProductName: 'Naples Brie Wheel Premium', + SupplierID: 23, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 142.25, + UnitsInStock: 119, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2014-12-23'), + }, + { + ProductID: 857, + ProductName: 'Gdansk Cabernet', + SupplierID: 2, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 238.99, + UnitsInStock: 85, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2020-05-04'), + }, + { + ProductID: 858, + ProductName: 'Athens Wasabi Paste Farmhouse', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 141.99, + UnitsInStock: 64, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2019-01-03'), + }, + { + ProductID: 859, + ProductName: 'Marrakesh Nougat Bars Selection', + SupplierID: 21, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 60.25, + UnitsInStock: 60, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2001-09-12'), + }, + { + ProductID: 860, + ProductName: 'Helsinki Sardines Traditional', + SupplierID: 20, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 4.25, + UnitsInStock: 128, + UnitsOnOrder: 30, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2009-06-17'), + }, + { + ProductID: 861, + ProductName: 'Gustafs Green Tea Classic', + SupplierID: 19, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 81.99, + UnitsInStock: 66, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2000-06-27'), + }, + { + ProductID: 862, + ProductName: 'Cape Town Anchovies Classic', + SupplierID: 6, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 133.99, + UnitsInStock: 21, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2004-01-09'), + }, + { + ProductID: 863, + ProductName: 'Rotterdam Harissa Extra', + SupplierID: 18, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 221.95, + UnitsInStock: 94, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2015-06-18'), + }, + { + ProductID: 864, + ProductName: 'Escargot Sesame Crunch Gold', + SupplierID: 21, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 96.99, + UnitsInStock: 13, + UnitsOnOrder: 100, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2011-06-02'), + }, + { + ProductID: 865, + ProductName: 'Lisbon Eel Fillets Classic', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 184.95, + UnitsInStock: 123, + UnitsOnOrder: 60, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2007-07-17'), + }, + { + ProductID: 866, + ProductName: 'Bergen Barbecue Sauce Selection', + SupplierID: 12, + CategoryID: 2, + QuantityPerUnit: '24 - 250 ml bottles', + UnitPrice: 79.95, + UnitsInStock: 59, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2014-06-20'), + }, + { + ProductID: 867, + ProductName: 'Shanghai Tortillas Farmhouse', + SupplierID: 14, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 162.5, + UnitsInStock: 68, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2001-04-04'), + }, + { + ProductID: 868, + ProductName: 'Uncle Bobs Smoked Ham Gold', + SupplierID: 3, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 155.99, + UnitsInStock: 48, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2004-10-28'), + }, + { + ProductID: 869, + ProductName: 'Valencia Lemon Tarts', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 153.95, + UnitsInStock: 138, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2008-01-28'), + }, + { + ProductID: 870, + ProductName: 'Porto Red Peppers Deluxe', + SupplierID: 8, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 132.0, + UnitsInStock: 70, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2020-03-13'), + }, + { + ProductID: 871, + ProductName: 'Naples Licorice Drops Traditional', + SupplierID: 5, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 91.95, + UnitsInStock: 32, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2004-01-09'), + }, + { + ProductID: 872, + ProductName: 'Odessa Lobster Tails Selection', + SupplierID: 6, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 68.25, + UnitsInStock: 26, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2006-09-07'), + }, + { + ProductID: 873, + ProductName: 'Malaga Mascarpone Gold', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 199.75, + UnitsInStock: 40, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-07-17'), + }, + { + ProductID: 874, + ProductName: 'Louisiana Egg Noodles Extra', + SupplierID: 28, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 194.0, + UnitsInStock: 109, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2007-11-15'), + }, + { + ProductID: 875, + ProductName: 'Nantes Sparkling Water Artisan', + SupplierID: 23, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 105.99, + UnitsInStock: 129, + UnitsOnOrder: 60, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2002-01-28'), + }, + { + ProductID: 876, + ProductName: 'Gustafs Butter Extra', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 35.25, + UnitsInStock: 31, + UnitsOnOrder: 20, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-08-28'), + }, + { + ProductID: 877, + ProductName: 'Gustafs Squid Rings Original', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 215.95, + UnitsInStock: 60, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2014-11-22'), + }, + { + ProductID: 878, + ProductName: 'Nantes Stout Extra', + SupplierID: 4, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 59.99, + UnitsInStock: 85, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-09-11'), + }, + { + ProductID: 879, + ProductName: 'Graz Beef Jerky Original', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 48.95, + UnitsInStock: 19, + UnitsOnOrder: 25, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-06-20'), + }, + { + ProductID: 880, + ProductName: 'Genoa Sriracha Farmhouse', + SupplierID: 10, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 194.99, + UnitsInStock: 150, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2008-11-14'), + }, + { + ProductID: 881, + ProductName: 'Verona Elderflower Cordial Classic', + SupplierID: 9, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 175.75, + UnitsInStock: 64, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2013-01-13'), + }, + { + ProductID: 882, + ProductName: 'Salzburg Duck Confit Artisan', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 133.25, + UnitsInStock: 121, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2004-12-04'), + }, + { + ProductID: 883, + ProductName: 'Odessa Camembert Farmhouse', + SupplierID: 2, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 197.5, + UnitsInStock: 120, + UnitsOnOrder: 50, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-06-26'), + }, + { + ProductID: 884, + ProductName: 'Tallinn Basmati Rice', + SupplierID: 20, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 12.75, + UnitsInStock: 50, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-10-15'), + }, + { + ProductID: 885, + ProductName: 'Lima Quinoa', + SupplierID: 25, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 195.99, + UnitsInStock: 137, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2018-01-02'), + }, + { + ProductID: 886, + ProductName: 'Bratislava Praline Mix Premium', + SupplierID: 21, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 142.95, + UnitsInStock: 61, + UnitsOnOrder: 15, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2014-02-22'), + }, + { + ProductID: 887, + ProductName: 'Aberdeen Avocados Selection', + SupplierID: 6, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 113.75, + UnitsInStock: 5, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2006-06-01'), + }, + { + ProductID: 888, + ProductName: 'Oslo Avocados Classic', + SupplierID: 17, + CategoryID: 7, + QuantityPerUnit: '12 - 1 lb pkgs.', + UnitPrice: 195.25, + UnitsInStock: 91, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-04-06'), + }, + { + ProductID: 889, + ProductName: 'Seville Mango Nectar Gold', + SupplierID: 22, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 144.75, + UnitsInStock: 62, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2020-11-17'), + }, + { + ProductID: 890, + ProductName: 'Tallinn Tonic Water Deluxe', + SupplierID: 12, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 39.5, + UnitsInStock: 119, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-05-09'), + }, + { + ProductID: 891, + ProductName: 'Athens Muesli Classic', + SupplierID: 17, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 203.95, + UnitsInStock: 120, + UnitsOnOrder: 50, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2005-03-13'), + }, + { + ProductID: 892, + ProductName: 'Bruges Cod Fillets Original', + SupplierID: 10, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 5.75, + UnitsInStock: 108, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2017-03-26'), + }, + { + ProductID: 893, + ProductName: 'Odessa Rice Vermicelli Premium', + SupplierID: 8, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 186.75, + UnitsInStock: 1, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2013-06-07'), + }, + { + ProductID: 894, + ProductName: 'Ravenna Tuna Steaks Traditional', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 117.75, + UnitsInStock: 107, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2012-07-17'), + }, + { + ProductID: 895, + ProductName: 'Basel Sardines Selection', + SupplierID: 25, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 76.0, + UnitsInStock: 36, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2009-08-25'), + }, + { + ProductID: 896, + ProductName: 'Bombay Pilsner', + SupplierID: 18, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 51.99, + UnitsInStock: 0, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2018-07-18'), + }, + { + ProductID: 897, + ProductName: 'Bergen Chorizo Deluxe', + SupplierID: 24, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 12.0, + UnitsInStock: 19, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-04-02'), + }, + { + ProductID: 898, + ProductName: 'Ljubljana Semolina Farmhouse', + SupplierID: 22, + CategoryID: 5, + QuantityPerUnit: '24 - 250 g pkgs.', + UnitPrice: 95.5, + UnitsInStock: 67, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2015-10-05'), + }, + { + ProductID: 899, + ProductName: 'Toscana Barley Water', + SupplierID: 3, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 7.75, + UnitsInStock: 141, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2009-10-10'), + }, + { + ProductID: 900, + ProductName: 'Graz Olive Oil Artisan', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 26.95, + UnitsInStock: 106, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2007-04-26'), + }, + { + ProductID: 901, + ProductName: 'Gustafs Quail Breasts Reserve', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 106.75, + UnitsInStock: 81, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2000-11-21'), + }, + { + ProductID: 902, + ProductName: 'Shanghai Pomegranates Farmhouse', + SupplierID: 22, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 115.99, + UnitsInStock: 100, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-11-04'), + }, + { + ProductID: 903, + ProductName: 'Athens Baby Spinach Premium', + SupplierID: 19, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 176.95, + UnitsInStock: 113, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2009-09-19'), + }, + { + ProductID: 904, + ProductName: 'Gdansk Smoked Salmon Traditional', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 6.0, + UnitsInStock: 80, + UnitsOnOrder: 10, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2016-09-03'), + }, + { + ProductID: 905, + ProductName: 'Helsinki Sesame Crunch Deluxe', + SupplierID: 16, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 177.5, + UnitsInStock: 123, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2016-05-04'), + }, + { + ProductID: 906, + ProductName: 'Nordsee Cocoa Drink Classic', + SupplierID: 25, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 188.99, + UnitsInStock: 141, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2016-10-24'), + }, + { + ProductID: 907, + ProductName: 'Aberdeen Cream Cheese Classic', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 55.5, + UnitsInStock: 119, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2019-02-24'), + }, + { + ProductID: 908, + ProductName: 'Nantes Smoked Salmon Selection', + SupplierID: 16, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 225.25, + UnitsInStock: 99, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2015-01-11'), + }, + { + ProductID: 909, + ProductName: 'Bergen Quail Breasts Original', + SupplierID: 7, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 118.0, + UnitsInStock: 37, + UnitsOnOrder: 70, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2008-12-09'), + }, + { + ProductID: 910, + ProductName: 'Gdansk Chorizo Classic', + SupplierID: 9, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 41.95, + UnitsInStock: 26, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2004-10-15'), + }, + { + ProductID: 911, + ProductName: 'Toscana Whole Wheat Flour', + SupplierID: 16, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 216.0, + UnitsInStock: 140, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-03-26'), + }, + { + ProductID: 912, + ProductName: 'Chef Antons Mixed Olives Original', + SupplierID: 23, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 99.25, + UnitsInStock: 94, + UnitsOnOrder: 60, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2015-09-17'), + }, + { + ProductID: 913, + ProductName: 'Granada Pork Loin Extra', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 51.99, + UnitsInStock: 5, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2004-12-23'), + }, + { + ProductID: 914, + ProductName: 'Pavlova Leeks', + SupplierID: 24, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 40.0, + UnitsInStock: 137, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2013-07-23'), + }, + { + ProductID: 915, + ProductName: 'Highland Shortbread Traditional', + SupplierID: 3, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 210.5, + UnitsInStock: 0, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2011-10-11'), + }, + { + ProductID: 916, + ProductName: 'Porto Black Pudding Selection', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 23.99, + UnitsInStock: 74, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2003-02-11'), + }, + { + ProductID: 917, + ProductName: 'Lisbon Portobello Mushrooms Artisan', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 220.25, + UnitsInStock: 79, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-08-04'), + }, + { + ProductID: 918, + ProductName: 'Rotterdam Apple Juice Deluxe', + SupplierID: 24, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 107.5, + UnitsInStock: 19, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-10-21'), + }, + { + ProductID: 919, + ProductName: 'Alpen Pilsner Traditional', + SupplierID: 21, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 191.25, + UnitsInStock: 66, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2014-05-06'), + }, + { + ProductID: 920, + ProductName: 'Escargot Barbecue Sauce Artisan', + SupplierID: 17, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 78.99, + UnitsInStock: 109, + UnitsOnOrder: 25, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2005-06-17'), + }, + { + ProductID: 921, + ProductName: 'Sicilian Plaice Fillets Reserve', + SupplierID: 13, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 110.0, + UnitsInStock: 108, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2016-01-21'), + }, + { + ProductID: 922, + ProductName: 'Bergen Brie Wheel Gold', + SupplierID: 18, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 91.95, + UnitsInStock: 128, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2001-06-01'), + }, + { + ProductID: 923, + ProductName: 'Seville Egg Noodles Reserve', + SupplierID: 16, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 109.5, + UnitsInStock: 75, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2009-04-02'), + }, + { + ProductID: 924, + ProductName: 'Malaga Mango Nectar Farmhouse', + SupplierID: 6, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 115.5, + UnitsInStock: 90, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2011-12-01'), + }, + { + ProductID: 925, + ProductName: 'Shanghai Curry Paste Classic', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 48.25, + UnitsInStock: 16, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2002-12-07'), + }, + { + ProductID: 926, + ProductName: 'Valencia Oat Flakes Selection', + SupplierID: 17, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 192.95, + UnitsInStock: 136, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2010-04-17'), + }, + { + ProductID: 927, + ProductName: 'Salzburg Dried Apples Gold', + SupplierID: 17, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 197.0, + UnitsInStock: 57, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2008-11-07'), + }, + { + ProductID: 928, + ProductName: 'Toscana Lobster Tails Deluxe', + SupplierID: 18, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 196.95, + UnitsInStock: 45, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2008-09-02'), + }, + { + ProductID: 929, + ProductName: 'Nantes Shrimp Mix Original', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 213.25, + UnitsInStock: 80, + UnitsOnOrder: 10, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2015-06-02'), + }, + { + ProductID: 930, + ProductName: 'Cascade Tahini Premium', + SupplierID: 20, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 198.99, + UnitsInStock: 56, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2006-02-05'), + }, + { + ProductID: 931, + ProductName: 'Salzburg Artichoke Hearts Premium', + SupplierID: 25, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 166.25, + UnitsInStock: 23, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-09-24'), + }, + { + ProductID: 932, + ProductName: 'Aberdeen Cocoa Drink Selection', + SupplierID: 21, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 129.0, + UnitsInStock: 104, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2009-05-11'), + }, + { + ProductID: 933, + ProductName: 'Basel Cabernet Traditional', + SupplierID: 7, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 32.95, + UnitsInStock: 3, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-08-03'), + }, + { + ProductID: 934, + ProductName: 'Nantes Caviar', + SupplierID: 9, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 121.0, + UnitsInStock: 28, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2007-01-07'), + }, + { + ProductID: 935, + ProductName: 'Ljubljana Stollen Extra', + SupplierID: 6, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 58.0, + UnitsInStock: 67, + UnitsOnOrder: 70, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2009-11-20'), + }, + { + ProductID: 936, + ProductName: 'Tallinn Curry Paste Extra', + SupplierID: 24, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 131.75, + UnitsInStock: 96, + UnitsOnOrder: 50, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2017-07-18'), + }, + { + ProductID: 937, + ProductName: 'Gustafs Roasted Chestnuts Gold', + SupplierID: 17, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 22.25, + UnitsInStock: 47, + UnitsOnOrder: 15, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2003-06-23'), + }, + { + ProductID: 938, + ProductName: 'Athens Balsamic Vinegar Deluxe', + SupplierID: 8, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 207.75, + UnitsInStock: 68, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2014-01-10'), + }, + { + ProductID: 939, + ProductName: 'Porto Avocados Classic', + SupplierID: 21, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 80.0, + UnitsInStock: 4, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2013-04-10'), + }, + { + ProductID: 940, + ProductName: 'Graz Amaranth Gold', + SupplierID: 2, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 166.99, + UnitsInStock: 108, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2003-02-22'), + }, + { + ProductID: 941, + ProductName: 'Basel Goose Liver Farmhouse', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 7.95, + UnitsInStock: 111, + UnitsOnOrder: 30, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2011-12-06'), + }, + { + ProductID: 942, + ProductName: 'Chef Antons Nougat Bars Farmhouse', + SupplierID: 1, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 172.5, + UnitsInStock: 79, + UnitsOnOrder: 50, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2012-10-18'), + }, + { + ProductID: 943, + ProductName: 'Provence Lobster Tails Farmhouse', + SupplierID: 8, + CategoryID: 8, + QuantityPerUnit: '16 - 250 g tins', + UnitPrice: 142.0, + UnitsInStock: 126, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2013-02-15'), + }, + { + ProductID: 944, + ProductName: 'Andalusia Leeks Selection', + SupplierID: 7, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 230.95, + UnitsInStock: 2, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2009-04-07'), + }, + { + ProductID: 945, + ProductName: 'Valencia Herring Fillets Original', + SupplierID: 18, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 134.0, + UnitsInStock: 129, + UnitsOnOrder: 100, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2019-01-01'), + }, + { + ProductID: 946, + ProductName: 'Bucharest Emmental Reserve', + SupplierID: 21, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 121.75, + UnitsInStock: 35, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2006-10-03'), + }, + { + ProductID: 947, + ProductName: 'Utrecht Feta Extra', + SupplierID: 6, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 51.99, + UnitsInStock: 66, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2016-05-06'), + }, + { + ProductID: 948, + ProductName: 'Copenhagen Honey Cakes Deluxe', + SupplierID: 13, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 20.5, + UnitsInStock: 62, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-02-12'), + }, + { + ProductID: 949, + ProductName: 'Sofia Chicken Breast Deluxe', + SupplierID: 24, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 153.95, + UnitsInStock: 24, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2018-03-23'), + }, + { + ProductID: 950, + ProductName: 'Nantes Rum Balls', + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 177.75, + UnitsInStock: 84, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2005-08-19'), + }, + { + ProductID: 951, + ProductName: 'Cairo Peanut Sauce Classic', + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 17.75, + UnitsInStock: 45, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2003-08-01'), + }, + { + ProductID: 952, + ProductName: 'Seville Crab Meat Reserve', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 82.95, + UnitsInStock: 1, + UnitsOnOrder: 10, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2015-10-14'), + }, + { + ProductID: 953, + ProductName: 'Verona Smoked Ham Selection', + SupplierID: 25, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 179.75, + UnitsInStock: 119, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2001-03-09'), + }, + { + ProductID: 954, + ProductName: 'Uncle Bobs Cold Brew Original', + SupplierID: 13, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 165.25, + UnitsInStock: 107, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2016-08-13'), + }, + { + ProductID: 955, + ProductName: 'Graz Squid Rings Farmhouse', + SupplierID: 7, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 105.0, + UnitsInStock: 142, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-09-01'), + }, + { + ProductID: 956, + ProductName: 'Pavlova Octopus Original', + SupplierID: 12, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 49.75, + UnitsInStock: 120, + UnitsOnOrder: 40, + ReorderLevel: 15, + Discontinued: true, + OrderDate: new Date('2017-01-17'), + }, + { + ProductID: 957, + ProductName: 'Cairo Rice Crackers Original', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 185.99, + UnitsInStock: 50, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2003-03-06'), + }, + { + ProductID: 958, + ProductName: 'Salzburg Lager Farmhouse', + SupplierID: 14, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 141.95, + UnitsInStock: 32, + UnitsOnOrder: 50, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2005-03-05'), + }, + { + ProductID: 959, + ProductName: 'Bucharest Tuna Steaks Reserve', + SupplierID: 19, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 212.5, + UnitsInStock: 146, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: true, + OrderDate: new Date('2018-04-04'), + }, + { + ProductID: 960, + ProductName: 'Vilnius Cream Cheese Selection', + SupplierID: 4, + CategoryID: 4, + QuantityPerUnit: '24 - 150 g cups', + UnitPrice: 159.99, + UnitsInStock: 9, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2001-07-04'), + }, + { + ProductID: 961, + ProductName: 'Uncle Bobs Buttermilk', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 240.0, + UnitsInStock: 14, + UnitsOnOrder: 20, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2006-09-11'), + }, + { + ProductID: 962, + ProductName: 'Marrakesh Shortbread Classic', + SupplierID: 14, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 178.75, + UnitsInStock: 47, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2009-05-14'), + }, + { + ProductID: 963, + ProductName: 'Sofia Turkey Roast Extra', + SupplierID: 23, + CategoryID: 6, + QuantityPerUnit: '24 - 250 g packs', + UnitPrice: 137.5, + UnitsInStock: 125, + UnitsOnOrder: 30, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-03-24'), + }, + { + ProductID: 964, + ProductName: 'Genoa Red Peppers Classic', + SupplierID: 6, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 61.75, + UnitsInStock: 104, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2004-03-23'), + }, + { + ProductID: 965, + ProductName: 'Bombay Rye Bread Mix Gold', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 240.99, + UnitsInStock: 10, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2017-08-25'), + }, + { + ProductID: 966, + ProductName: 'Verona Chorizo Deluxe', + SupplierID: 23, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 227.25, + UnitsInStock: 78, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2004-10-26'), + }, + { + ProductID: 967, + ProductName: 'Bucharest Elderflower Cordial Original', + SupplierID: 13, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 217.95, + UnitsInStock: 3, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-11-03'), + }, + { + ProductID: 968, + ProductName: 'Graz Pastrami Classic', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 191.5, + UnitsInStock: 75, + UnitsOnOrder: 25, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2018-01-17'), + }, + { + ProductID: 969, + ProductName: 'Granada Blue Mussels Farmhouse', + SupplierID: 3, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 163.25, + UnitsInStock: 130, + UnitsOnOrder: 50, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2004-01-10'), + }, + { + ProductID: 970, + ProductName: 'Shanghai Chocolate Truffles Classic', + SupplierID: 22, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 78.75, + UnitsInStock: 136, + UnitsOnOrder: 15, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2020-01-25'), + }, + { + ProductID: 971, + ProductName: 'Valencia Halibut Steaks Traditional', + SupplierID: 28, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 180.99, + UnitsInStock: 129, + UnitsOnOrder: 15, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2020-04-26'), + }, + { + ProductID: 972, + ProductName: 'Vienna Rum Balls Classic', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 15.5, + UnitsInStock: 139, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-04-25'), + }, + { + ProductID: 973, + ProductName: 'Rotterdam Butter', + SupplierID: 19, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 146.0, + UnitsInStock: 150, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2020-10-08'), + }, + { + ProductID: 974, + ProductName: 'Genoa Plaice Fillets Deluxe', + SupplierID: 15, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 238.95, + UnitsInStock: 131, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-04-25'), + }, + { + ProductID: 975, + ProductName: 'Porto Dried Apricots Deluxe', + SupplierID: 20, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 4.5, + UnitsInStock: 75, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2003-06-02'), + }, + { + ProductID: 976, + ProductName: 'Sofia Ginger Root Reserve', + SupplierID: 12, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 101.99, + UnitsInStock: 14, + UnitsOnOrder: 20, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2017-02-12'), + }, + { + ProductID: 977, + ProductName: 'Nantes Apple Juice Original', + SupplierID: 8, + CategoryID: 1, + QuantityPerUnit: '6 - 1 L bottles', + UnitPrice: 31.99, + UnitsInStock: 142, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2016-10-23'), + }, + { + ProductID: 978, + ProductName: 'Utrecht Cider Extra', + SupplierID: 10, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 141.25, + UnitsInStock: 32, + UnitsOnOrder: 40, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-10-17'), + }, + { + ProductID: 979, + ProductName: 'Athens Granola Original', + SupplierID: 15, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 41.25, + UnitsInStock: 67, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2018-03-28'), + }, + { + ProductID: 980, + ProductName: 'Cape Town Iced Tea Original', + SupplierID: 15, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 162.95, + UnitsInStock: 14, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2018-01-17'), + }, + { + ProductID: 981, + ProductName: 'Zurich Duck Confit Deluxe', + SupplierID: 16, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 37.95, + UnitsInStock: 44, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-08-25'), + }, + { + ProductID: 982, + ProductName: 'Pavlova Muesli Selection', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 81.75, + UnitsInStock: 130, + UnitsOnOrder: 60, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2005-07-14'), + }, + { + ProductID: 983, + ProductName: 'Nordsee Kefir Deluxe', + SupplierID: 4, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 11.25, + UnitsInStock: 105, + UnitsOnOrder: 60, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2012-10-01'), + }, + { + ProductID: 984, + ProductName: 'Nordsee Oat Flakes Classic', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 33.25, + UnitsInStock: 127, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2012-11-16'), + }, + { + ProductID: 985, + ProductName: 'Graz Rose Wine Classic', + SupplierID: 28, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 216.99, + UnitsInStock: 41, + UnitsOnOrder: 20, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2017-02-10'), + }, + { + ProductID: 986, + ProductName: 'Grandma Kellys Coconut Bars', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 121.75, + UnitsInStock: 69, + UnitsOnOrder: 20, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2004-01-21'), + }, + { + ProductID: 987, + ProductName: 'Helsinki Nougat Bars Artisan', + SupplierID: 19, + CategoryID: 3, + QuantityPerUnit: '48 pieces', + UnitPrice: 120.25, + UnitsInStock: 148, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-07-04'), + }, + { + ProductID: 988, + ProductName: 'Seville King Prawns Gold', + SupplierID: 3, + CategoryID: 8, + QuantityPerUnit: '12 - 500 g packs', + UnitPrice: 221.0, + UnitsInStock: 67, + UnitsOnOrder: 10, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2011-10-25'), + }, + { + ProductID: 989, + ProductName: 'Dublin Cream Cheese Original', + SupplierID: 7, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 192.95, + UnitsInStock: 55, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2009-03-11'), + }, + { + ProductID: 990, + ProductName: 'Naples Mozzarella Reserve', + SupplierID: 17, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 55.25, + UnitsInStock: 137, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2004-01-01'), + }, + { + ProductID: 991, + ProductName: 'Cairo Whipping Cream Gold', + SupplierID: 28, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 189.75, + UnitsInStock: 109, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2007-03-28'), + }, + { + ProductID: 992, + ProductName: 'Bombay Pesto Classic', + SupplierID: 14, + CategoryID: 2, + QuantityPerUnit: '12 - 550 ml bottles', + UnitPrice: 99.5, + UnitsInStock: 9, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2013-01-11'), + }, + { + ProductID: 993, + ProductName: 'Bratislava Truffle Oil Artisan', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '18 - 500 g pkgs.', + UnitPrice: 69.95, + UnitsInStock: 103, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2010-07-23'), + }, + { + ProductID: 994, + ProductName: 'Krakow Barley Water Classic', + SupplierID: 17, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 45.25, + UnitsInStock: 13, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2006-03-15'), + }, + { + ProductID: 995, + ProductName: 'Ljubljana Barley Water Deluxe', + SupplierID: 3, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 151.5, + UnitsInStock: 30, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2003-03-07'), + }, + { + ProductID: 996, + ProductName: 'Nordsee Blue Cheese Farmhouse', + SupplierID: 28, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 59.0, + UnitsInStock: 4, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2011-04-14'), + }, + { + ProductID: 997, + ProductName: 'Vienna Buckwheat Extra', + SupplierID: 25, + CategoryID: 5, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 27.0, + UnitsInStock: 65, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: true, + OrderDate: new Date('2020-05-19'), + }, + { + ProductID: 998, + ProductName: 'Ghent Provolone Original', + SupplierID: 19, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 222.75, + UnitsInStock: 39, + UnitsOnOrder: 60, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2017-02-22'), + }, + { + ProductID: 999, + ProductName: 'Reykjavik Tuna Steaks Gold', + SupplierID: 14, + CategoryID: 8, + QuantityPerUnit: '20 - 150 g jars', + UnitPrice: 6.95, + UnitsInStock: 106, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2005-10-25'), + }, + { + ProductID: 1000, + ProductName: 'Genoa Seaweed Salad Gold', + SupplierID: 27, + CategoryID: 8, + QuantityPerUnit: '24 - 200 g cans', + UnitPrice: 67.75, + UnitsInStock: 4, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2016-07-18'), + }, + { + ProductID: 1001, + ProductName: 'Granada Pork Loin Premium', + SupplierID: 21, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 103.25, + UnitsInStock: 70, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2014-03-16'), + }, + { + ProductID: 1002, + ProductName: 'Graz Mozzarella Artisan', + SupplierID: 27, + CategoryID: 4, + QuantityPerUnit: '1 kg pkg.', + UnitPrice: 190.25, + UnitsInStock: 44, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2009-02-06'), + }, + { + ProductID: 1003, + ProductName: 'Grandma Kellys Manchego', + SupplierID: 22, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 108.99, + UnitsInStock: 95, + UnitsOnOrder: 70, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2017-08-02'), + }, + { + ProductID: 1004, + ProductName: 'Odessa Hazelnut Cream Deluxe', + SupplierID: 26, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 121.75, + UnitsInStock: 112, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2005-06-16'), + }, + { + ProductID: 1005, + ProductName: 'Krakow Cabernet Selection', + SupplierID: 27, + CategoryID: 1, + QuantityPerUnit: '12 - 750 ml bottles', + UnitPrice: 105.25, + UnitsInStock: 83, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2007-10-06'), + }, + { + ProductID: 1006, + ProductName: 'Gdansk Muesli Classic', + SupplierID: 7, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 125.5, + UnitsInStock: 75, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2015-12-20'), + }, + { + ProductID: 1007, + ProductName: 'Bergen Brie Wheel Extra', + SupplierID: 13, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 196.0, + UnitsInStock: 16, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2018-06-27'), + }, + { + ProductID: 1008, + ProductName: 'Basel Stollen Traditional', + SupplierID: 25, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 49.0, + UnitsInStock: 20, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2002-04-18'), + }, + { + ProductID: 1009, + ProductName: 'Bergen Bratwurst Deluxe', + SupplierID: 13, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 203.5, + UnitsInStock: 63, + UnitsOnOrder: 50, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2008-11-13'), + }, + { + ProductID: 1010, + ProductName: 'Ravenna Oat Flakes', + SupplierID: 18, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 40.95, + UnitsInStock: 26, + UnitsOnOrder: 100, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2007-05-27'), + }, + { + ProductID: 1011, + ProductName: 'Naples Bratwurst Reserve', + SupplierID: 10, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 102.99, + UnitsInStock: 90, + UnitsOnOrder: 50, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-10-16'), + }, + { + ProductID: 1012, + ProductName: 'Basel Chorizo Classic', + SupplierID: 16, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 201.25, + UnitsInStock: 103, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2009-03-07'), + }, + { + ProductID: 1013, + ProductName: 'Brisbane Gruyere Deluxe', + SupplierID: 15, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 194.0, + UnitsInStock: 68, + UnitsOnOrder: 50, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2020-02-06'), + }, + { + ProductID: 1014, + ProductName: 'Ghent Cornmeal Deluxe', + SupplierID: 3, + CategoryID: 5, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 22.5, + UnitsInStock: 102, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2009-11-14'), + }, + { + ProductID: 1015, + ProductName: 'Naples Lemon Tarts Classic', + SupplierID: 13, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 162.75, + UnitsInStock: 72, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2017-10-09'), + }, + { + ProductID: 1016, + ProductName: 'Porto Beef Brisket Classic', + SupplierID: 28, + CategoryID: 6, + QuantityPerUnit: '10 - 1 kg trays', + UnitPrice: 90.95, + UnitsInStock: 61, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2015-02-01'), + }, + { + ProductID: 1017, + ProductName: 'Krakow Quinoa Artisan', + SupplierID: 20, + CategoryID: 5, + QuantityPerUnit: '10 - 2 kg sacks', + UnitPrice: 114.25, + UnitsInStock: 82, + UnitsOnOrder: 40, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2003-05-11'), + }, + { + ProductID: 1018, + ProductName: 'Bruges Mayonnaise Traditional', + SupplierID: 16, + CategoryID: 2, + QuantityPerUnit: '12 - 8 oz jars', + UnitPrice: 16.5, + UnitsInStock: 52, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2002-07-08'), + }, + { + ProductID: 1019, + ProductName: 'Cairo Ginger Beer', + SupplierID: 12, + CategoryID: 1, + QuantityPerUnit: '12 - 355 ml cans', + UnitPrice: 194.25, + UnitsInStock: 61, + UnitsOnOrder: 20, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2020-01-22'), + }, + { + ProductID: 1020, + ProductName: 'Bordeaux Spelt Flour', + SupplierID: 21, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 124.75, + UnitsInStock: 67, + UnitsOnOrder: 10, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2012-07-15'), + }, + { + ProductID: 1021, + ProductName: 'Aberdeen Quinoa Original', + SupplierID: 17, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 150.75, + UnitsInStock: 62, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2003-01-27'), + }, + { + ProductID: 1022, + ProductName: 'Ljubljana Polenta Artisan', + SupplierID: 28, + CategoryID: 5, + QuantityPerUnit: '16 - 750 g pkgs.', + UnitPrice: 138.5, + UnitsInStock: 135, + UnitsOnOrder: 25, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2008-06-21'), + }, + { + ProductID: 1023, + ProductName: 'Andalusia Crab Meat Original', + SupplierID: 1, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 93.25, + UnitsInStock: 111, + UnitsOnOrder: 25, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2008-03-14'), + }, + { + ProductID: 1024, + ProductName: 'Dublin Mango Nectar Original', + SupplierID: 23, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 109.99, + UnitsInStock: 111, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2003-10-02'), + }, + { + ProductID: 1025, + ProductName: 'Riga Brownie Bites Reserve', + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: '10 pkgs.', + UnitPrice: 50.25, + UnitsInStock: 132, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-09-24'), + }, + { + ProductID: 1026, + ProductName: 'Istanbul Leeks Farmhouse', + SupplierID: 10, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 153.75, + UnitsInStock: 121, + UnitsOnOrder: 30, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2012-08-08'), + }, + { + ProductID: 1027, + ProductName: 'Sicilian Sriracha Artisan', + SupplierID: 19, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 65.75, + UnitsInStock: 98, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2020-10-11'), + }, + { + ProductID: 1028, + ProductName: 'Louisiana Crayfish Premium', + SupplierID: 5, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 152.25, + UnitsInStock: 58, + UnitsOnOrder: 0, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2020-09-10'), + }, + { + ProductID: 1029, + ProductName: 'Kyoto Iced Tea Artisan', + SupplierID: 7, + CategoryID: 1, + QuantityPerUnit: '24 - 12 oz bottles', + UnitPrice: 5.25, + UnitsInStock: 13, + UnitsOnOrder: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2019-01-23'), + }, + { + ProductID: 1030, + ProductName: 'Vilnius Chestnut Mushrooms Deluxe', + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: '10 kg box', + UnitPrice: 211.99, + UnitsInStock: 131, + UnitsOnOrder: 10, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2015-02-15'), + }, + { + ProductID: 1031, + ProductName: 'Helsinki Fruit Gums Reserve', + SupplierID: 6, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 30.99, + UnitsInStock: 27, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2013-08-01'), + }, + { + ProductID: 1032, + ProductName: 'Ghent Parmesan Shavings Original', + SupplierID: 2, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 108.99, + UnitsInStock: 80, + UnitsOnOrder: 40, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2000-03-18'), + }, + { + ProductID: 1033, + ProductName: 'Tokyo Mango Nectar Classic', + SupplierID: 22, + CategoryID: 1, + QuantityPerUnit: '10 boxes x 20 bags', + UnitPrice: 14.95, + UnitsInStock: 43, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2015-04-04'), + }, + { + ProductID: 1034, + ProductName: 'Oslo Parmesan Shavings Reserve', + SupplierID: 10, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 168.25, + UnitsInStock: 140, + UnitsOnOrder: 0, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2012-05-27'), + }, + { + ProductID: 1035, + ProductName: 'Marrakesh Lemons Reserve', + SupplierID: 23, + CategoryID: 7, + QuantityPerUnit: '32 - 500 g boxes', + UnitPrice: 60.99, + UnitsInStock: 10, + UnitsOnOrder: 15, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2006-11-13'), + }, + { + ProductID: 1036, + ProductName: 'Helsinki Manchego Selection', + SupplierID: 3, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 141.95, + UnitsInStock: 8, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date('2018-05-22'), + }, + { + ProductID: 1037, + ProductName: 'Genoa Sea Bass Premium', + SupplierID: 19, + CategoryID: 8, + QuantityPerUnit: '10 - 1 kg boxes', + UnitPrice: 220.75, + UnitsInStock: 29, + UnitsOnOrder: 100, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2013-05-19'), + }, + { + ProductID: 1038, + ProductName: 'Helsinki Leeks', + SupplierID: 8, + CategoryID: 7, + QuantityPerUnit: '24 - 300 g trays', + UnitPrice: 121.75, + UnitsInStock: 121, + UnitsOnOrder: 100, + ReorderLevel: 10, + Discontinued: true, + OrderDate: new Date('2003-06-25'), + }, + { + ProductID: 1039, + ProductName: 'Basel Shrimp Mix Original', + SupplierID: 14, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 56.75, + UnitsInStock: 49, + UnitsOnOrder: 25, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2008-06-23'), + }, + { + ProductID: 1040, + ProductName: 'Bruges Pork Loin Deluxe', + SupplierID: 26, + CategoryID: 6, + QuantityPerUnit: '12 - 500 g pkgs.', + UnitPrice: 27.75, + UnitsInStock: 33, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2008-10-04'), + }, + { + ProductID: 1041, + ProductName: 'Aberdeen Cheddar Blocks Selection', + SupplierID: 7, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 42.0, + UnitsInStock: 51, + UnitsOnOrder: 10, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2003-12-20'), + }, + { + ProductID: 1042, + ProductName: 'Vienna Octopus Premium', + SupplierID: 2, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 46.99, + UnitsInStock: 118, + UnitsOnOrder: 15, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2000-04-06'), + }, + { + ProductID: 1043, + ProductName: 'Uncle Bobs Halloumi Gold', + SupplierID: 28, + CategoryID: 4, + QuantityPerUnit: '12 - 200 g tubs', + UnitPrice: 34.5, + UnitsInStock: 102, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2013-08-08'), + }, + { + ProductID: 1044, + ProductName: 'Basel Parmesan Shavings Traditional', + SupplierID: 18, + CategoryID: 4, + QuantityPerUnit: '10 - 500 g pkgs.', + UnitPrice: 223.75, + UnitsInStock: 33, + UnitsOnOrder: 100, + ReorderLevel: 25, + Discontinued: true, + OrderDate: new Date('2012-11-22'), + }, + { + ProductID: 1045, + ProductName: 'Zagreb Salami', + SupplierID: 2, + CategoryID: 6, + QuantityPerUnit: '20 - 400 g packs', + UnitPrice: 59.75, + UnitsInStock: 105, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2016-11-16'), + }, + { + ProductID: 1046, + ProductName: 'Santiago Dried Figs Deluxe', + SupplierID: 1, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 208.75, + UnitsInStock: 2, + UnitsOnOrder: 60, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2020-05-14'), + }, + { + ProductID: 1047, + ProductName: 'Ghent Mackerel Classic', + SupplierID: 9, + CategoryID: 8, + QuantityPerUnit: '5 kg pkg.', + UnitPrice: 174.5, + UnitsInStock: 95, + UnitsOnOrder: 0, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2009-07-21'), + }, + { + ProductID: 1048, + ProductName: 'Brisbane Almond Biscotti Premium', + SupplierID: 16, + CategoryID: 3, + QuantityPerUnit: '24 - 50 g pkgs.', + UnitPrice: 173.0, + UnitsInStock: 122, + UnitsOnOrder: 20, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date('2002-09-07'), + }, + { + ProductID: 1049, + ProductName: 'Valencia Chorizo', + SupplierID: 1, + CategoryID: 6, + QuantityPerUnit: '16 kg pkg.', + UnitPrice: 13.95, + UnitsInStock: 90, + UnitsOnOrder: 20, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date('2016-04-22'), + }, + { + ProductID: 1050, + ProductName: 'Lisbon Tonic Water Deluxe', + SupplierID: 24, + CategoryID: 1, + QuantityPerUnit: '24 - 330 ml bottles', + UnitPrice: 83.0, + UnitsInStock: 32, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-07-01'), + }, + { + ProductID: 1051, + ProductName: 'Seville Cheddar Blocks Extra', + SupplierID: 8, + CategoryID: 4, + QuantityPerUnit: '15 - 300 g pkgs.', + UnitPrice: 68.75, + UnitsInStock: 142, + UnitsOnOrder: 15, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2006-09-10'), + }, + { + ProductID: 1052, + ProductName: 'Riga Chocolate Truffles Classic', + SupplierID: 6, + CategoryID: 3, + QuantityPerUnit: '12 - 100 g bars', + UnitPrice: 99.99, + UnitsInStock: 67, + UnitsOnOrder: 30, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2013-12-26'), + }, + { + ProductID: 1053, + ProductName: 'Nantes Cranberry Relish Artisan', + SupplierID: 5, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 125.0, + UnitsInStock: 80, + UnitsOnOrder: 20, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date('2000-06-15'), + }, + { + ProductID: 1054, + ProductName: 'Basel Balsamic Vinegar Classic', + SupplierID: 12, + CategoryID: 2, + QuantityPerUnit: '36 boxes', + UnitPrice: 223.95, + UnitsInStock: 115, + UnitsOnOrder: 70, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2009-09-03'), + }, + { + ProductID: 1055, + ProductName: 'Vienna Pomegranates Selection', + SupplierID: 20, + CategoryID: 7, + QuantityPerUnit: '20 - 250 g bags', + UnitPrice: 206.5, + UnitsInStock: 30, + UnitsOnOrder: 70, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2018-10-04'), + }, + { + ProductID: 1056, + ProductName: 'Uncle Bobs Leeks Artisan', + SupplierID: 11, + CategoryID: 7, + QuantityPerUnit: '6 - 2 kg crates', + UnitPrice: 83.0, + UnitsInStock: 75, + UnitsOnOrder: 30, + ReorderLevel: 20, + Discontinued: false, + OrderDate: new Date('2004-01-12'), + }, + { + ProductID: 1057, + ProductName: 'Santiago Horseradish Premium', + SupplierID: 11, + CategoryID: 2, + QuantityPerUnit: '12 - 200 ml jars', + UnitPrice: 14.0, + UnitsInStock: 63, + UnitsOnOrder: 100, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date('2008-03-23'), + }, + { + ProductID: 1058, + ProductName: 'Antwerp Basmati Rice Gold', + SupplierID: 7, + CategoryID: 5, + QuantityPerUnit: '20 - 1 kg bags', + UnitPrice: 180.95, + UnitsInStock: 90, + UnitsOnOrder: 70, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date('2002-04-14'), + }, + { + ProductID: 1059, + ProductName: 'Bratislava Gouda', + SupplierID: 20, + CategoryID: 4, + QuantityPerUnit: '5 kg wheel', + UnitPrice: 61.5, + UnitsInStock: 33, + UnitsOnOrder: 15, + ReorderLevel: 15, + Discontinued: false, + OrderDate: new Date('2013-03-17'), + }, + { + ProductID: 1060, + ProductName: 'Ljubljana Butter Cookies Traditional', + SupplierID: 28, + CategoryID: 3, + QuantityPerUnit: '16 kg box', + UnitPrice: 191.99, + UnitsInStock: 55, + UnitsOnOrder: 40, + ReorderLevel: 5, + Discontinued: true, + OrderDate: new Date('2019-07-11'), + }, +]; +/* tslint:enable */ diff --git a/src/app/virtualization-compare/virtualization-compare.sample.html b/src/app/virtualization-compare/virtualization-compare.sample.html new file mode 100644 index 00000000000..ac56fa2ee15 --- /dev/null +++ b/src/app/virtualization-compare/virtualization-compare.sample.html @@ -0,0 +1,337 @@ +
+
+

Virtualization comparison

+

+The same {{ total }} items are shown twice: *igxFor on the left, + <igx-virtual-scroll> on the right. Scroll either list, or press the button + below to have both measured automatically. +

+ +
+ + Content-sized item heights + + + + + + + + + + + + +
+
+ +
+
+ + + Both lists are scrolled to exactly the same positions and every frame is recorded. + Fast scroll = 40 big jumps, slow scroll = 60 small steps, each repeated 3 times. + Lower numbers are better, except for the number of rows. + +
+ + @if (results().length) { + + + + + + + + + + + @for (row of results(); track row.metric) { + + + + + + + } + +
Metric*igxForigx-virtual-scrollAhead
{{ row.metric }} ({{ row.unit }}){{ row.forOf }}{{ row.vs }} + {{ verdict(row) }} +
+ +

+ These are timings only. Whether a scroll leaves a visible blank cannot be judged from the + DOM — change detection may fill it in before the browser paints — so it is not measured + here. Use a screen recording for that. +

+ } +
+ + +
+ Show: + + + + +
+ @if (section() === 'lists') { +
+
+

+ *igxFor + worst frame {{ forOfMeter.worst() }} ms + + dropped {{ forOfMeter.dropped() }} / {{ forOfMeter.frames() }} + +

+ +
+
+ {{ i }} + {{ item.name }} + {{ item.detail }} +
+
+
+ +
+

+ igx-virtual-scroll + worst frame {{ vsMeter.worst() }} ms + + dropped {{ vsMeter.dropped() }} / {{ vsMeter.frames() }} + +

+ + + +
+ {{ i }} + {{ item.name }} + {{ item.detail }} +
+
+
+
+
+ + + } + + @if (section() === 'combo') { +
+

Combo over the same data

+

+ An igx-combo bound to all {{ total }} records, so the component can be tried + the way it is actually used rather than as a bare list. +

+ + + + +

+ Open the combo, then measure what the scroll engine assumes a row is. It should match a + real row; if it does not, the scrollbar is the wrong length and a scroll position maps to + the wrong item until the rows nearby have been measured. +

+ + + + @if (comboEstimate(); as est) { + + + + + + + + + + + + + + + + + + + +
Height of a rendered row{{ est.realRowHeight }} px
Height the engine assumes per item + {{ est.assumedPerItem }} px +
Scrollable height{{ est.trackHeight }} px
Scrollable height it should be{{ est.trackShouldBe }} px
+ } +
+ + } + + @if (section() === 'million') { +
+

A million records, two ways to bind them

+

+ Both hold the same {{ MILLION | number }} rows. The difference is how many of them + exist in the browser at once. +

+ +
Held in memory
+

+ The whole collection is one array on [data]. Nothing special is needed, + but building it takes a moment and it stays in memory for as long as the page is open. +

+ + @if (millionItems(); as items) { +

+ Built {{ items.length | number }} rows in {{ millionBuildMs() | number }} ms. +

+ +
+ + + + + +
+ + + + + } @else { + +

The page freezes while the array is built.

+ } + +
A page at a time
+

+ Only the rows the drop-down shows are ever created. totalItemCount tells the + combo how long the collection is, so the scrollbar spans all + {{ MILLION | number }} rows, and dataPreLoad asks for the window it needs as + you scroll. This is what a remote service would answer; here the rows are worked out from + their index. Filtering is off, since a real service would filter server-side. +

+ +
+
+ + +

+ Rows in memory: {{ pagedCombo.page().length }} · + window {{ pagedCombo.window() }} · + pages served: {{ pagedCombo.pagesServed() }} +

+
+ +
+ + +

+ Rows in memory: {{ pagedSimple.page().length }} · + window {{ pagedSimple.window() }} · + pages served: {{ pagedSimple.pagesServed() }} +

+
+
+ + +
+ + } + + @if (section() === 'dropdowns') { +
+

Drop-downs over the same data

+

+ The drop-down supports both projections; navigation and selection share one code path. +

+ +
+
+ + +
+ + {{ i }} - {{ item.name }} + +
+
+
+ +
+ + + + + + {{ i }} - {{ item.name }} + + + + +
+
+
+ } +
diff --git a/src/app/virtualization-compare/virtualization-compare.sample.scss b/src/app/virtualization-compare/virtualization-compare.sample.scss new file mode 100644 index 00000000000..b3a584a6b4c --- /dev/null +++ b/src/app/virtualization-compare/virtualization-compare.sample.scss @@ -0,0 +1,201 @@ +.vc { + display: flex; + flex-direction: column; + gap: 16px; + padding: 16px; + max-width: 1200px; +} + +.vc__header p { + margin: 4px 0 12px; + max-width: 70ch; +} + +.vc__controls { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 12px; + + label { + display: inline-flex; + align-items: center; + gap: 6px; + } + + input[type='number'] { + width: 96px; + padding: 4px 6px; + } +} + +.vc__bench { + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 4px; + padding: 12px 16px; + background: #fff; +} + +.vc__bench-head { + display: flex; + align-items: center; + gap: 16px; + flex-wrap: wrap; +} + +.vc__bench-note { + font-size: 12px; + color: rgba(0, 0, 0, 0.6); + max-width: 60ch; +} + +.vc__table { + width: 100%; + border-collapse: collapse; + margin-top: 12px; + font-size: 13px; + + th, + td { + text-align: left; + padding: 6px 10px; + border-bottom: 1px solid rgba(0, 0, 0, 0.08); + } + + th { + font-weight: 600; + color: rgba(0, 0, 0, 0.7); + } +} + +.vc__num { + text-align: right !important; + font-variant-numeric: tabular-nums; +} + +.vc__unit { + color: rgba(0, 0, 0, 0.45); +} + +.vc__verdict { + font-size: 12px; + color: rgba(0, 0, 0, 0.55); +} + +.vc__verdict--vs { + color: #2e7d32; + font-weight: 600; +} + +.vc__verdict--for { + color: #c62828; + font-weight: 600; +} + +.vc__panes { + display: grid; + // minmax(0, 1fr): a long row must not push its own column wider than the other. + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 16px; +} + +.vc__pane { + min-width: 0; +} + +.vc__pane h4 { + display: flex; + align-items: center; + gap: 8px; + margin: 0 0 8px; +} + +.vc__badge { + font-size: 12px; + font-weight: 400; + padding: 2px 8px; + border-radius: 10px; + background: rgba(0, 0, 0, 0.06); +} + +.vc__badge--warn { + background: rgba(233, 30, 99, 0.15); +} + +.vc__viewport { + display: block; + height: 480px; + border: 1px solid #ccc; + border-radius: 4px; +} + +// The *igxFor pane is a plain div, so it needs the scroll box the component gives itself. +div.vc__viewport { + position: relative; + overflow: auto; + background: #fff; +} + +.vc__row { + display: flex; + align-items: flex-start; + gap: 12px; + height: 48px; + padding: 0 12px; + border-bottom: 1px solid #efefef; + background: #fff; + box-sizing: border-box; + + // Both put back, to test whether they are what makes this list flicker. + overflow: hidden; + white-space: nowrap; +} + +// Content-sized mode: the row grows with its text. +.vc__viewport--auto .vc__row { + height: auto; + min-height: 48px; + padding: 8px 12px; + white-space: normal; +} + +.vc__index { + flex: 0 0 64px; + color: rgba(0, 0, 0, 0.5); + font-variant-numeric: tabular-nums; +} + +.vc__name { + flex: 0 0 160px; + font-weight: 600; +} + +.vc__detail { + flex: 1 1 auto; + color: rgba(0, 0, 0, 0.7); +} + +.vc__dropdowns { + p { + margin: 4px 0 12px; + max-width: 80ch; + } +} + +.vc__dd-row { + display: flex; + gap: 24px; +} + +.vc__dd-wrapper { + display: block; + position: relative; + height: 400px; + overflow: auto; +} + +.vc__footer p { + margin: 0; + max-width: 90ch; + color: rgba(0, 0, 0, 0.7); +} diff --git a/src/app/virtualization-compare/virtualization-compare.sample.ts b/src/app/virtualization-compare/virtualization-compare.sample.ts new file mode 100644 index 00000000000..e934dbed4ce --- /dev/null +++ b/src/app/virtualization-compare/virtualization-compare.sample.ts @@ -0,0 +1,603 @@ +import { + AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, NgZone, OnDestroy, inject, signal, viewChild +} from '@angular/core'; +import { IForOfState } from 'igniteui-angular/directives'; +import { IgxSimpleComboComponent } from 'igniteui-angular/simple-combo'; +import { DecimalPipe } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IgxButtonDirective, IgxForOfDirective, IgxToggleActionDirective } from 'igniteui-angular/directives'; +import { IgxVirtualScrollComponent, IgxVirtualItemDirective } from 'igniteui-angular/virtual-scroll'; +import { IgxDropDownComponent, IgxDropDownItemComponent, IgxDropDownItemNavigationDirective } from 'igniteui-angular/drop-down'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; +import { IgxComboBaseDirective, IgxComboComponent } from 'igniteui-angular/combo'; +import { + ConnectedPositioningStrategy, HorizontalAlignment, OverlaySettings, VerticalAlignment +} from 'igniteui-angular/core'; +import { DATA } from './data'; + +export interface CompareItem { + id: number; + name: string; + /** Text long enough to wrap over one to four lines when heights are content-sized. */ + detail: string; +} + +/** What the scroll engine assumes an item is, next to what it really is. */ +export interface SizeEstimate { + realRowHeight: number; + assumedPerItem: number; + trackHeight: number; + trackShouldBe: number; +} + +/** One row of the results table. */ +export interface BenchRow { + metric: string; + unit: string; + forOf: number; + vs: number; + /** Which way is better for this metric. */ + lowerIsBetter: boolean; +} + +/** The same source list ten times over, with ids kept unique. */ +function buildItems(seed: number): CompareItem[] { + return Array.from({ length: 10 }, (_, pass) => + DATA.map((record, index) => ({ + id: seed + pass * DATA.length + index, + name: record.ProductName, + detail: `${record.QuantityPerUnit} `.repeat(1 + (index % 4)).trim() + })) + ).flat(); +} + +const MILLION = 1_000_000; + +/** + * The item at a given index, worked out from the index instead of stored. A million of these + * exist as far as a combo is concerned; only the ones asked for are ever built. + */ +function millionItem(index: number): CompareItem { + const record = DATA[index % DATA.length]; + return { + id: index, + name: `${record.ProductName} #${index}`, + detail: record.QuantityPerUnit + }; +} + +function millionPage(startIndex: number, count: number): CompareItem[] { + const end = Math.min(startIndex + count, MILLION); + const page: CompareItem[] = []; + for (let i = Math.max(0, startIndex); i < end; i++) { + page.push(millionItem(i)); + } + return page; +} + +/** The page size to serve when the combo has not reported a window yet. */ +const FIRST_PAGE = 24; + +/** + * Rows to serve on each side of the window the combo asked for. Without it the first row + * scrolled into view is one the page does not cover yet, and shows up blank for a frame. + */ +const PAGE_MARGIN = 10; + +/** + * Stands in for a remote service over a million rows: it answers with the page the combo + * asks for and nothing else. Two combos each need their own, because each has its own + * scroll position and therefore its own window. + */ +class PagedMillion { + public readonly page = signal(millionPage(0, FIRST_PAGE)); + public readonly pagesServed = signal(0); + public readonly window = signal('0 - 23'); + + /** Answers a `dataPreLoad`: the combo reports the window, this fills it. */ + public serve(state: IForOfState): void { + const start = Math.max(0, (state.startIndex ?? 0) - PAGE_MARGIN); + const count = (state.chunkSize || FIRST_PAGE) + 2 * PAGE_MARGIN; + + this.page.set(millionPage(start, count)); + this.pagesServed.update(n => n + 1); + this.window.set(`${start} - ${Math.min(start + count, MILLION) - 1}`); + } +} + +/** A frame longer than this reads as a stutter. */ +const DROPPED_FRAME_MS = 20; +/** How often the live meters push their counters into the view. */ +const PUBLISH_EVERY_MS = 250; + +const frame = () => new Promise(resolve => requestAnimationFrame(resolve)); +const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + +/** Frame-time meter. Counts in fields, publishes rarely: a signal write per frame would itself + * schedule change detection at 60 Hz and look like the stutter being measured. */ +class FrameMeter { + public readonly worst = signal(0); + public readonly dropped = signal(0); + public readonly frames = signal(0); + + private _worst = 0; + private _dropped = 0; + private _frames = 0; + private _handle = 0; + private _publishedAt = 0; + + public reset(): void { + this._worst = this._dropped = this._frames = this._publishedAt = 0; + this.publish(); + } + + public tick(): void { + if (this._handle) { + return; + } + const start = performance.now(); + this._handle = requestAnimationFrame(() => { + this._handle = 0; + const elapsed = performance.now() - start; + + this._frames++; + this._worst = Math.max(this._worst, elapsed); + if (elapsed > DROPPED_FRAME_MS) { + this._dropped++; + } + + const now = performance.now(); + if (now - this._publishedAt > PUBLISH_EVERY_MS) { + this._publishedAt = now; + this.publish(); + } + }); + } + + public publish(): void { + this.worst.set(Math.round(this._worst * 10) / 10); + this.dropped.set(this._dropped); + this.frames.set(this._frames); + } +} + +/** The two elements a benchmark needs: the visible box, and whatever actually scrolls. */ +interface Target { + viewport: HTMLElement; + scroller: HTMLElement; +} + +@Component({ + selector: 'app-virtualization-compare-sample', + templateUrl: './virtualization-compare.sample.html', + styleUrls: ['./virtualization-compare.sample.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + DecimalPipe, + FormsModule, + IgxForOfDirective, + IgxVirtualScrollComponent, + IgxVirtualItemDirective, + IgxButtonDirective, + IgxSwitchComponent, + IgxDropDownComponent, + IgxDropDownItemComponent, + IgxDropDownItemNavigationDirective, + IgxToggleActionDirective, + IgxComboComponent, + IgxSimpleComboComponent + ] +}) +export class VirtualizationCompareSampleComponent implements AfterViewInit, OnDestroy { + private readonly zone = inject(NgZone); + private readonly teardown: Array<() => void> = []; + + protected readonly forOfDir = viewChild>(IgxForOfDirective); + protected readonly virtualScroll = viewChild>('virtualScroll'); + // read: ElementRef must be given at runtime; the generic alone would return the component. + protected readonly virtualScrollRef = viewChild('virtualScroll', { read: ElementRef }); + protected readonly forOfHost = viewChild>('forOfHost'); + + /** + * One array per pane, built from the same seed so both hold identical data. They are + * separate signals so that replacing the data of one does not re-render the other and + * put its work inside the measurement. + */ + protected readonly forOfItems = signal(buildItems(0)); + protected readonly vsItems = signal(buildItems(0)); + /** Content-sized items, which is what the two engines disagree about most. */ + protected readonly variableHeights = signal(false); + protected readonly targetIndex = signal(5000); + + protected readonly forOfMeter = new FrameMeter(); + protected readonly vsMeter = new FrameMeter(); + + protected readonly results = signal([]); + protected readonly comboEstimate = signal(null); + protected readonly running = signal(''); + + /** + * Only one section is rendered at a time. Several virtualized lists over the same 10,600 + * items on one page compete for the main thread, which shows up as dropped frames in + * whichever one you happen to be scrolling. + */ + protected readonly section = signal<'lists' | 'combo' | 'dropdowns' | 'million'>('lists'); + + /** Extra rows kept rendered above and below the viewport. */ + protected readonly overScan = signal(2); + protected readonly itemSize = 48; + protected readonly containerSize = 480; + + /** Opens upwards; the drop-downs sit low on the page. */ + protected readonly dropUp: OverlaySettings = { + closeOnOutsideClick: true, + modal: false, + positionStrategy: new ConnectedPositioningStrategy({ + horizontalDirection: HorizontalAlignment.Right, + horizontalStartPoint: HorizontalAlignment.Left, + verticalDirection: VerticalAlignment.Top, + verticalStartPoint: VerticalAlignment.Top + }) + }; + + protected get total(): number { + return this.vsItems().length; + } + + protected readonly MILLION = MILLION; + + /** A million rows held as one array, built on demand: it costs a few hundred megabytes. */ + protected readonly millionItems = signal(null); + protected readonly millionBuildMs = signal(0); + + /** The same million served a page at a time, which costs a page. */ + protected readonly pagedCombo = new PagedMillion(); + protected readonly pagedSimple = new PagedMillion(); + + private readonly pagedComboRef = viewChild('pagedComboRef'); + private readonly pagedSimpleRef = viewChild('pagedSimpleRef'); + + /** Materializes the million. Blocks for a moment, which is the point of the button. */ + protected buildMillion(): void { + const start = performance.now(); + const items = new Array(MILLION); + + for (let i = 0; i < MILLION; i++) { + items[i] = millionItem(i); + } + + this.millionBuildMs.set(Math.round(performance.now() - start)); + this.millionItems.set(items); + } + + protected releaseMillion(): void { + this.millionItems.set(null); + this.millionBuildMs.set(0); + } + + /** + * Serves the window the combo reports. `totalItemCount` is what makes the scrollbar span + * the whole collection while the array holds one page. + */ + protected servePage(combo: IgxComboBaseDirective, source: PagedMillion): void { + combo.totalItemCount = MILLION; + source.serve(combo.virtualizationState); + } + + public ngAfterViewInit(): void { + // Set before the first window is rendered, so the scrollbar starts out the right length. + for (const combo of [this.pagedComboRef(), this.pagedSimpleRef()]) { + if (combo) { + combo.totalItemCount = MILLION; + } + } + + // Outside Angular: a (scroll) template binding would run CD on every scroll event. + this.zone.runOutsideAngular(() => { + for (const [element, meter] of this.meterTargets()) { + const handler = () => meter.tick(); + element.addEventListener('scroll', handler, { passive: true, capture: true }); + this.teardown.push(() => + element.removeEventListener('scroll', handler, { capture: true } as any)); + } + }); + } + + public ngOnDestroy(): void { + this.teardown.forEach(fn => fn()); + } + + private meterTargets(): Array<[HTMLElement, FrameMeter]> { + const pairs: Array<[HTMLElement | undefined, FrameMeter]> = [ + [this.forOfHost()?.nativeElement, this.forOfMeter], + [this.virtualScrollRef()?.nativeElement as HTMLElement | undefined, this.vsMeter] + ]; + return pairs.filter((pair): pair is [HTMLElement, FrameMeter] => !!pair[0]); + } + + //#region Manual controls + + protected resetMeters(): void { + this.forOfMeter.reset(); + this.vsMeter.reset(); + } + + /** Flushes whatever the meters collected since their last publish. */ + protected refreshMeters(): void { + this.forOfMeter.publish(); + this.vsMeter.publish(); + } + + protected toggleHeights(value: boolean): void { + this.variableHeights.set(value); + this.resetMeters(); + } + + protected async scrollBoth(): Promise { + const index = Math.max(0, Math.min(this.total - 1, this.targetIndex())); + this.resetMeters(); + this.forOfDir()?.scrollTo(index); + await this.virtualScroll()?.scrollToIndex(index); + } + + /** Twelve large jumps, so the blank frames are visible by eye. */ + protected async flingBoth(): Promise { + this.resetMeters(); + for (let i = 0; i < 12; i++) { + const index = Math.round(this.total * ((i * 0.37 + 0.11) % 1)); + this.forOfDir()?.scrollTo(index); + void this.virtualScroll()?.scrollToIndex(index); + await delay(120); + } + this.refreshMeters(); + } + + protected scrollTop(): void { + this.resetMeters(); + this.forOfDir()?.scrollTo(0); + void this.virtualScroll()?.scrollToIndex(0); + } + + //#endregion + + //#region Benchmark + + /** The visible box and the element that scrolls, for each engine. */ + private target(which: 'forOf' | 'vs'): Target | null { + if (which === 'vs') { + const host = this.virtualScrollRef()?.nativeElement as HTMLElement | undefined; + return host ? { viewport: host, scroller: host } : null; + } + const viewport = this.forOfHost()?.nativeElement; + const scroller = this.forOfDir()?.getScroll(); + return viewport && scroller ? { viewport, scroller } : null; + } + + /** Pixels of the visible box no rendered row covers; near the viewport height means empty. */ + private uncovered({ viewport }: Target): number { + const box = viewport.getBoundingClientRect(); + const rects = Array.from(viewport.querySelectorAll('.vc__row')) + .map(row => row.getBoundingClientRect()); + + if (!rects.length) { + return Math.round(box.height); + } + + const top = Math.min(...rects.map(r => r.top)); + const bottom = Math.max(...rects.map(r => r.bottom)); + return Math.round(Math.max(0, top - box.top) + Math.max(0, box.bottom - bottom)); + } + + /** Drives one engine through `steps` positions, one per frame, recording what each frame cost. */ + private async sweep(which: 'forOf' | 'vs', steps: number, stepPx: number) { + const target = this.target(which); + if (!target) { + return null; + } + + target.scroller.scrollTop = 0; + target.scroller.dispatchEvent(new Event('scroll')); + await frame(); await frame(); await frame(); + + const frames: number[] = []; + let last = performance.now(); + + for (let i = 1; i <= steps; i++) { + target.scroller.scrollTop = i * stepPx; + target.scroller.dispatchEvent(new Event('scroll')); + await frame(); + + const now = performance.now(); + frames.push(now - last); + last = now; + } + + return { + worstFrame: Math.max(...frames), + droppedFrames: frames.filter(f => f > DROPPED_FRAME_MS).length, + sampled: steps + }; + } + + /** Median of several sweeps; frame timings swing too much for a single pass to prove anything. */ + private async sweepMedian(which: 'forOf' | 'vs', steps: number, stepPx: number, passes = 3) { + const runs: Array>>> = []; + for (let i = 0; i < passes; i++) { + const result = await this.sweep(which, steps, stepPx); + if (result) { + runs.push(result); + } + } + if (!runs.length) { + return null; + } + + const median = (pick: (r: typeof runs[0]) => number) => { + const values = runs.map(pick).sort((a, b) => a - b); + return values[Math.floor(values.length / 2)]; + }; + + return { + worstFrame: median(r => r.worstFrame), + droppedFrames: median(r => r.droppedFrames), + sampled: runs[0].sampled + }; + } + + /** Time from asking for an index until a row carrying it is actually on screen. */ + private async seekLatency(which: 'forOf' | 'vs', index: number): Promise { + const target = this.target(which); + if (!target) { + return 0; + } + + target.scroller.scrollTop = 0; + target.scroller.dispatchEvent(new Event('scroll')); + await frame(); await frame(); + + const start = performance.now(); + if (which === 'vs') { + void this.virtualScroll()?.scrollToIndex(index); + } else { + this.forOfDir()?.scrollTo(index); + } + + // Wait until a rendered row reports the index we asked for. + for (let i = 0; i < 120; i++) { + await frame(); + const found = Array.from(target.viewport.querySelectorAll('.vc__index')) + .some(el => Number(el.textContent) === index); + if (found) { + break; + } + } + return performance.now() - start; + } + + /** Time from swapping the whole data array until rows are on screen again. */ + private async rebindLatency(which: 'forOf' | 'vs'): Promise { + const target = this.target(which); + if (!target) { + return 0; + } + + const items = buildItems(Math.round(Math.random() * 1e6)); + const start = performance.now(); + this.zone.run(() => (which === 'vs' ? this.vsItems : this.forOfItems).set(items)); + + for (let i = 0; i < 120; i++) { + await frame(); + if (target.viewport.querySelectorAll('.vc__row').length > 0 && this.uncovered(target) < 4) { + break; + } + } + return performance.now() - start; + } + + /** Runs every scenario against both engines and fills the results table. */ + protected async runBenchmark(): Promise { + const rows: BenchRow[] = []; + const add = (metric: string, unit: string, forOf: number, vs: number, lowerIsBetter = true) => + rows.push({ + metric, unit, lowerIsBetter, + forOf: Math.round(forOf * 10) / 10, + vs: Math.round(vs * 10) / 10 + }); + + await this.zone.runOutsideAngular(async () => { + this.setRunning('fast scroll'); + const flingFor = await this.sweepMedian('forOf', 40, 600); + const flingVs = await this.sweepMedian('vs', 40, 600); + + this.setRunning('slow scroll'); + const steadyFor = await this.sweepMedian('forOf', 60, 160); + const steadyVs = await this.sweepMedian('vs', 60, 160); + + this.setRunning('jump to a far item'); + const seekFor = await this.medianOf(() => this.seekLatency('forOf', this.total - 200)); + const seekVs = await this.medianOf(() => this.seekLatency('vs', this.total - 200)); + + this.setRunning('replacing the data'); + const bindFor = await this.rebindLatency('forOf'); + const bindVs = await this.rebindLatency('vs'); + + if (flingFor && flingVs) { + add('Fast scroll - slowest frame', 'ms', flingFor.worstFrame, flingVs.worstFrame); + add('Fast scroll - frames slower than 20ms', `of ${flingFor.sampled}`, flingFor.droppedFrames, flingVs.droppedFrames); + } + if (steadyFor && steadyVs) { + add('Slow scroll - slowest frame', 'ms', steadyFor.worstFrame, steadyVs.worstFrame); + add('Slow scroll - frames slower than 20ms', `of ${steadyFor.sampled}`, steadyFor.droppedFrames, steadyVs.droppedFrames); + } + add('Jump to a far item - time until it is visible', 'ms', seekFor, seekVs); + add('Replace all the data - time until rows are back', 'ms', bindFor, bindVs); + add('Rows kept in the DOM', 'rows', this.countRows('forOf'), this.countRows('vs'), false); + add('DOM elements in the list', 'elements', this.countNodes('forOf'), this.countNodes('vs')); + }); + + this.zone.run(() => { + this.results.set(rows); + this.running.set(''); + this.refreshMeters(); + }); + } + + /** Median of three passes of any single-number measurement. */ + private async medianOf(measure: () => Promise, passes = 3): Promise { + const values: number[] = []; + for (let i = 0; i < passes; i++) { + values.push(await measure()); + } + values.sort((a, b) => a - b); + return values[Math.floor(values.length / 2)]; + } + + /** + * Reads what the engine assumes an item is from the height of the track, and compares it + * with a row that is actually rendered. They should match; a difference means the scroll + * position maps to the wrong item until the rows around it have been measured. + */ + protected measureComboEstimate(): void { + const host = document.querySelector('.igx-combo__content igx-virtual-scroll'); + const row = host?.querySelector('.igx-drop-down__item'); + const track = host?.querySelector('.igx-vs__track'); + + if (!host || !row || !track) { + this.comboEstimate.set(null); + return; + } + + const realRowHeight = Math.round(row.getBoundingClientRect().height * 10) / 10; + const trackHeight = Math.round(track.getBoundingClientRect().height); + + this.comboEstimate.set({ + realRowHeight, + assumedPerItem: Math.round(trackHeight / this.total * 10) / 10, + trackHeight, + trackShouldBe: Math.round(realRowHeight * this.total) + }); + } + + private setRunning(label: string): void { + this.zone.run(() => this.running.set(label)); + } + + private countRows(which: 'forOf' | 'vs'): number { + return this.target(which)?.viewport.querySelectorAll('.vc__row').length ?? 0; + } + + private countNodes(which: 'forOf' | 'vs'): number { + return this.target(which)?.viewport.querySelectorAll('*').length ?? 0; + } + + /** Names the engine that comes out ahead on a row, for the table's last column. */ + protected verdict(row: BenchRow): string { + if (row.forOf === row.vs) { + return 'tie'; + } + const vsWins = row.lowerIsBetter ? row.vs < row.forOf : row.vs > row.forOf; + return vsWins ? 'igx-virtual-scroll' : '*igxFor'; + } + + //#endregion +}