Просмотр исходного кода

feat(admin-ui): Add controls for stockOnHand & trackInventory

Relates to #81
Michael Bromley 6 лет назад
Родитель
Сommit
4e021b8314

+ 4 - 0
admin-ui/src/app/catalog/components/product-detail/product-detail.component.ts

@@ -39,6 +39,8 @@ export interface VariantFormValue {
     priceIncludesTax: boolean;
     priceWithTax: number;
     taxCategoryId: string;
+    stockOnHand: number;
+    trackInventory: boolean;
     facetValueIds: string[];
 }
 
@@ -372,6 +374,8 @@ export class ProductDetailComponent extends BaseDetailComponent<ProductWithVaria
                 priceIncludesTax: variant.priceIncludesTax,
                 priceWithTax: variant.priceWithTax,
                 taxCategoryId: variant.taxCategory.id,
+                stockOnHand: variant.stockOnHand,
+                trackInventory: variant.trackInventory,
                 facetValueIds,
             };
 

+ 119 - 103
admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.html

@@ -8,117 +8,133 @@
 </div>
 <div class="variants-list">
     <div class="variant-container card" *ngFor="let variant of variants; let i = index">
-        <div class="card-block header-row">
-            <div class="toggle">
-                <vdr-select-toggle
-                    size="small"
-                    [selected]="isVariantSelected(variant.id)"
-                    (selectedChange)="toggleSelectVariant(variant.id)"
-                ></vdr-select-toggle>
-            </div>
-            <div class="details">
-                <div class="sku">
-                    <clr-input-container>
-                        <input
-                            clrInput
-                            type="text"
-                            [formControl]="formArray.get([i, 'sku'])"
-                            [placeholder]="'catalog.sku' | translate"
-                        />
-                    </clr-input-container>
+        <ng-container [formGroup]="formArray.at(i)">
+            <div class="card-block header-row">
+                <div class="toggle">
+                    <vdr-select-toggle
+                        size="small"
+                        [selected]="isVariantSelected(variant.id)"
+                        (selectedChange)="toggleSelectVariant(variant.id)"
+                    ></vdr-select-toggle>
                 </div>
-                <div class="name">
-                    <clr-input-container>
-                        <input
-                            clrInput
-                            type="text"
-                            [formControl]="formArray.get([i, 'name'])"
-                            [placeholder]="'common.name' | translate"
-                        />
-                    </clr-input-container>
+                <div class="details">
+                    <div class="sku">
+                        <clr-input-container>
+                            <input
+                                clrInput
+                                type="text"
+                                formControlName="sku"
+                                [placeholder]="'catalog.sku' | translate"
+                            />
+                        </clr-input-container>
+                    </div>
+                    <div class="name">
+                        <clr-input-container>
+                            <input
+                                clrInput
+                                type="text"
+                                formControlName="name"
+                                [placeholder]="'common.name' | translate"
+                            />
+                        </clr-input-container>
+                    </div>
                 </div>
-            </div>
-            <div *ngIf="variant.options.length">
-                <div class="options">
-                    {{ 'catalog.options' | translate }}:
-                    <vdr-chip *ngFor="let option of variant.options">{{ option.name }}</vdr-chip>
+                <div *ngIf="variant.options.length">
+                    <div class="options">
+                        {{ 'catalog.options' | translate }}:
+                        <vdr-chip *ngFor="let option of variant.options">{{ option.name }}</vdr-chip>
+                    </div>
                 </div>
-            </div>
-            <div class="flex-spacer"></div>
-            <div>
-                <clr-toggle-wrapper>
-                    <input
-                        type="checkbox"
-                        clrToggle
-                        name="enabled"
-                        [formControl]="formArray.get([i, 'enabled'])"
-                    />
-                    <label>{{ 'common.enabled' | translate }}</label>
-                </clr-toggle-wrapper>
-            </div>
-        </div>
-        <div class="card-block">
-            <div class="row">
-                <div class="assets">
-                    <vdr-product-assets
-                        [compact]="true"
-                        [assets]="variant.assets"
-                        [featuredAsset]="variant.featuredAsset"
-                        (change)="onAssetChange(variant.id, $event)"
-                    ></vdr-product-assets>
+                <div class="flex-spacer"></div>
+                <div>
+                    <clr-toggle-wrapper>
+                        <input type="checkbox" clrToggle name="enabled" formControlName="enabled" />
+                        <label>{{ 'common.enabled' | translate }}</label>
+                    </clr-toggle-wrapper>
                 </div>
-                <div class="col">
-                    <div class="pricing">
-                        <div class="tax-category">
-                            <clr-select-container>
-                                <label>{{ 'catalog.tax-category' | translate }}</label>
-                                <select
-                                    clrSelect
-                                    name="options"
-                                    [formControl]="formArray.get([i, 'taxCategoryId'])"
-                                >
-                                    <option
-                                        *ngFor="let taxCategory of taxCategories"
-                                        [value]="taxCategory.id"
-                                    >
-                                        {{ taxCategory.name }}
-                                    </option>
-                                </select>
-                            </clr-select-container>
-                        </div>
-                        <div class="price">
-                            <clr-input-container>
-                                <label>{{ 'catalog.price' | translate }}</label>
-                                <vdr-currency-input
-                                    clrInput
-                                    [currencyCode]="variant.currencyCode"
-                                    [formControl]="formArray.get([i, 'price'])"
-                                ></vdr-currency-input>
-                            </clr-input-container>
+            </div>
+            <div class="card-block">
+                <div class="row">
+                    <div class="assets">
+                        <vdr-product-assets
+                            [compact]="true"
+                            [assets]="variant.assets"
+                            [featuredAsset]="variant.featuredAsset"
+                            (change)="onAssetChange(variant.id, $event)"
+                        ></vdr-product-assets>
+                    </div>
+                    <div class="col">
+                        <div class="pricing">
+                            <div class="tax-category">
+                                <clr-select-container>
+                                    <label>{{ 'catalog.tax-category' | translate }}</label>
+                                    <select clrSelect name="options" formControlName="taxCategoryId">
+                                        <option
+                                            *ngFor="let taxCategory of taxCategories"
+                                            [value]="taxCategory.id"
+                                        >
+                                            {{ taxCategory.name }}
+                                        </option>
+                                    </select>
+                                </clr-select-container>
+                            </div>
+                            <div class="price">
+                                <clr-input-container>
+                                    <label>{{ 'catalog.price' | translate }}</label>
+                                    <vdr-currency-input
+                                        clrInput
+                                        [currencyCode]="variant.currencyCode"
+                                        formControlName="price"
+                                    ></vdr-currency-input>
+                                </clr-input-container>
+                            </div>
+                            <vdr-variant-price-detail
+                                [price]="formArray.get([i, 'price'])!.value"
+                                [currencyCode]="variant.currencyCode"
+                                [priceIncludesTax]="variant.priceIncludesTax"
+                                [taxCategoryId]="formArray.get([i, 'taxCategoryId'])!.value"
+                            ></vdr-variant-price-detail>
+                            <div class="stock">
+                                <clr-input-container>
+                                    <label>{{ 'catalog.stock-on-hand' | translate }}</label>
+                                    <input
+                                        clrInput
+                                        type="number"
+                                        min="0"
+                                        step="1"
+                                        formControlName="stockOnHand"
+                                    />
+                                </clr-input-container>
+                            </div>
+                            <div class="stock">
+                                <clr-checkbox-wrapper>
+                                    <input
+                                        type="checkbox"
+                                        clrCheckbox
+                                        name="trackInventory"
+                                        formControlName="trackInventory"
+                                    />
+                                    <label>{{ 'catalog.track-inventory' | translate }}</label>
+                                </clr-checkbox-wrapper>
+                            </div>
                         </div>
-                        <vdr-variant-price-detail
-                            [price]="formArray.get([i, 'price'])!.value"
-                            [currencyCode]="variant.currencyCode"
-                            [priceIncludesTax]="variant.priceIncludesTax"
-                            [taxCategoryId]="formArray.get([i, 'taxCategoryId'])!.value"
-                        ></vdr-variant-price-detail>
                     </div>
                 </div>
             </div>
-        </div>
-        <div class="card-block">
-            <div class="facets">
-                <vdr-facet-value-chip
-                    *ngFor="let facetValue of existingFacetValues(i)"
-                    [facetValue]="facetValue"
-                    (remove)="removeFacetValue(i, facetValue.id)"
-                ></vdr-facet-value-chip>
-                <vdr-facet-value-chip
-                    *ngFor="let facetValue of pendingFacetValues(i)"
-                    [facetValue]="facetValue"
-                    (remove)="removeFacetValue(i, facetValue.id)"
-                ></vdr-facet-value-chip>
+            <div class="card-block">
+                <div class="facets">
+                    <vdr-facet-value-chip
+                        *ngFor="let facetValue of existingFacetValues(i)"
+                        [facetValue]="facetValue"
+                        (remove)="removeFacetValue(i, facetValue.id)"
+                    ></vdr-facet-value-chip>
+                    <vdr-facet-value-chip
+                        *ngFor="let facetValue of pendingFacetValues(i)"
+                        [facetValue]="facetValue"
+                        (remove)="removeFacetValue(i, facetValue.id)"
+                    ></vdr-facet-value-chip>
+                </div>
             </div>
-        </div>
+        </ng-container>
     </div>
 </div>

+ 2 - 0
admin-ui/src/app/data/definitions/product-definitions.ts

@@ -22,6 +22,8 @@ export const PRODUCT_VARIANT_FRAGMENT = gql`
         currencyCode
         priceIncludesTax
         priceWithTax
+        stockOnHand
+        trackInventory
         taxRateApplied {
             id
             name

+ 2 - 0
admin-ui/src/app/data/providers/product-data.service.ts

@@ -134,6 +134,8 @@ export class ProductDataService {
                     'facetValueIds',
                     'featuredAssetId',
                     'assetIds',
+                    'trackInventory',
+                    'stockOnHand',
                 ]),
             ),
         };

+ 2 - 0
admin-ui/src/i18n-messages/en.json

@@ -77,8 +77,10 @@
     "set-as-featured-asset": "Set as featured asset",
     "sku": "SKU",
     "slug": "Slug",
+    "stock-on-hand": "Stock",
     "tax-category": "Tax category",
     "taxes": "Taxes",
+    "track-inventory": "Track inventory",
     "truncated-options-count": "{count} further {count, plural, one {option} other {options}}",
     "upload-assets": "Upload assets",
     "values": "Values",

+ 1 - 1
packages/common/src/generated-shop-types.ts

@@ -1,5 +1,5 @@
 // tslint:disable
-// Generated in 2019-05-02T12:27:28+02:00
+// Generated in 2019-05-02T20:00:05+02:00
 export type Maybe<T> = T | null;
 
 export interface OrderListOptions {

+ 103 - 99
packages/common/src/generated-types.ts

@@ -1,5 +1,5 @@
 // tslint:disable
-// Generated in 2019-05-02T12:27:29+02:00
+// Generated in 2019-05-02T20:00:06+02:00
 export type Maybe<T> = T | null;
 
 
@@ -555,18 +555,18 @@ export interface PromotionFilterParameter {
   enabled?: Maybe<BooleanOperators>;
 }
 
-export interface RoleListOptions {
+export interface ShippingMethodListOptions {
   
   skip?: Maybe<number>;
   
   take?: Maybe<number>;
   
-  sort?: Maybe<RoleSortParameter>;
+  sort?: Maybe<ShippingMethodSortParameter>;
   
-  filter?: Maybe<RoleFilterParameter>;
+  filter?: Maybe<ShippingMethodFilterParameter>;
 }
 
-export interface RoleSortParameter {
+export interface ShippingMethodSortParameter {
   
   id?: Maybe<SortOrder>;
   
@@ -579,7 +579,7 @@ export interface RoleSortParameter {
   description?: Maybe<SortOrder>;
 }
 
-export interface RoleFilterParameter {
+export interface ShippingMethodFilterParameter {
   
   createdAt?: Maybe<DateOperators>;
   
@@ -590,18 +590,18 @@ export interface RoleFilterParameter {
   description?: Maybe<StringOperators>;
 }
 
-export interface ShippingMethodListOptions {
+export interface RoleListOptions {
   
   skip?: Maybe<number>;
   
   take?: Maybe<number>;
   
-  sort?: Maybe<ShippingMethodSortParameter>;
+  sort?: Maybe<RoleSortParameter>;
   
-  filter?: Maybe<ShippingMethodFilterParameter>;
+  filter?: Maybe<RoleFilterParameter>;
 }
 
-export interface ShippingMethodSortParameter {
+export interface RoleSortParameter {
   
   id?: Maybe<SortOrder>;
   
@@ -614,7 +614,7 @@ export interface ShippingMethodSortParameter {
   description?: Maybe<SortOrder>;
 }
 
-export interface ShippingMethodFilterParameter {
+export interface RoleFilterParameter {
   
   createdAt?: Maybe<DateOperators>;
   
@@ -834,20 +834,6 @@ export interface UpdateCountryInput {
   enabled?: Maybe<boolean>;
 }
 
-export interface CreateCustomerGroupInput {
-  
-  name: string;
-  
-  customerIds?: Maybe<string[]>;
-}
-
-export interface UpdateCustomerGroupInput {
-  
-  id: string;
-  
-  name?: Maybe<string>;
-}
-
 export interface CreateCustomerInput {
   
   title?: Maybe<string>;
@@ -1013,6 +999,20 @@ export interface UpdateFacetValueInput {
   customFields?: Maybe<Json>;
 }
 
+export interface CreateCustomerGroupInput {
+  
+  name: string;
+  
+  customerIds?: Maybe<string[]>;
+}
+
+export interface UpdateCustomerGroupInput {
+  
+  id: string;
+  
+  name?: Maybe<string>;
+}
+
 export interface UpdateGlobalSettingsInput {
   
   availableLanguages?: Maybe<LanguageCode[]>;
@@ -1182,16 +1182,18 @@ export interface UpdatePromotionInput {
   actions?: Maybe<ConfigurableOperationInput[]>;
 }
 
-export interface CreateRoleInput {
+export interface CreateShippingMethodInput {
   
   code: string;
   
   description: string;
   
-  permissions: Permission[];
+  checker: ConfigurableOperationInput;
+  
+  calculator: ConfigurableOperationInput;
 }
 
-export interface UpdateRoleInput {
+export interface UpdateShippingMethodInput {
   
   id: string;
   
@@ -1199,21 +1201,21 @@ export interface UpdateRoleInput {
   
   description?: Maybe<string>;
   
-  permissions?: Maybe<Permission[]>;
+  checker?: Maybe<ConfigurableOperationInput>;
+  
+  calculator?: Maybe<ConfigurableOperationInput>;
 }
 
-export interface CreateShippingMethodInput {
+export interface CreateRoleInput {
   
   code: string;
   
   description: string;
   
-  checker: ConfigurableOperationInput;
-  
-  calculator: ConfigurableOperationInput;
+  permissions: Permission[];
 }
 
-export interface UpdateShippingMethodInput {
+export interface UpdateRoleInput {
   
   id: string;
   
@@ -1221,9 +1223,7 @@ export interface UpdateShippingMethodInput {
   
   description?: Maybe<string>;
   
-  checker?: Maybe<ConfigurableOperationInput>;
-  
-  calculator?: Maybe<ConfigurableOperationInput>;
+  permissions?: Maybe<Permission[]>;
 }
 
 export interface CreateTaxCategoryInput {
@@ -4102,6 +4102,10 @@ export namespace ProductVariant {
     
     priceWithTax: number;
     
+    stockOnHand: number;
+    
+    trackInventory: boolean;
+    
     taxRateApplied: TaxRateApplied;
     
     taxCategory: TaxCategory;
@@ -4627,10 +4631,6 @@ export interface Query {
   
   country?: Maybe<Country>;
   
-  customerGroups: CustomerGroup[];
-  
-  customerGroup?: Maybe<CustomerGroup>;
-  
   customers: CustomerList;
   
   customer?: Maybe<Customer>;
@@ -4639,6 +4639,10 @@ export interface Query {
   
   facet?: Maybe<Facet>;
   
+  customerGroups: CustomerGroup[];
+  
+  customerGroup?: Maybe<CustomerGroup>;
+  
   globalSettings: GlobalSettings;
   
   order?: Maybe<Order>;
@@ -4665,10 +4669,6 @@ export interface Query {
   
   adjustmentOperations: AdjustmentOperations;
   
-  roles: RoleList;
-  
-  role?: Maybe<Role>;
-  
   shippingMethods: ShippingMethodList;
   
   shippingMethod?: Maybe<ShippingMethod>;
@@ -4677,6 +4677,10 @@ export interface Query {
   
   shippingCalculators: ConfigurableOperation[];
   
+  roles: RoleList;
+  
+  role?: Maybe<Role>;
+  
   taxCategories: TaxCategory[];
   
   taxCategory?: Maybe<TaxCategory>;
@@ -5769,17 +5773,17 @@ export interface AdjustmentOperations {
 }
 
 
-export interface RoleList extends PaginatedList {
+export interface ShippingMethodList extends PaginatedList {
   
-  items: Role[];
+  items: ShippingMethod[];
   
   totalItems: number;
 }
 
 
-export interface ShippingMethodList extends PaginatedList {
+export interface RoleList extends PaginatedList {
   
-  items: ShippingMethod[];
+  items: Role[];
   
   totalItems: number;
 }
@@ -5844,14 +5848,6 @@ export interface Mutation {
   updateCountry: Country;
   /** Delete a Country */
   deleteCountry: DeletionResponse;
-  /** Create a new CustomerGroup */
-  createCustomerGroup: CustomerGroup;
-  /** Update an existing CustomerGroup */
-  updateCustomerGroup: CustomerGroup;
-  /** Add Customers to a CustomerGroup */
-  addCustomersToGroup: CustomerGroup;
-  /** Remove Customers from a CustomerGroup */
-  removeCustomersFromGroup: CustomerGroup;
   /** Create a new Customer. If a password is provided, a new User will also be created an linked to the Customer. */
   createCustomer: Customer;
   /** Update an existing Customer */
@@ -5876,6 +5872,14 @@ export interface Mutation {
   updateFacetValues: FacetValue[];
   /** Delete one or more FacetValues */
   deleteFacetValues: DeletionResponse[];
+  /** Create a new CustomerGroup */
+  createCustomerGroup: CustomerGroup;
+  /** Update an existing CustomerGroup */
+  updateCustomerGroup: CustomerGroup;
+  /** Add Customers to a CustomerGroup */
+  addCustomersToGroup: CustomerGroup;
+  /** Remove Customers from a CustomerGroup */
+  removeCustomersFromGroup: CustomerGroup;
   
   updateGlobalSettings: GlobalSettings;
   
@@ -5908,14 +5912,14 @@ export interface Mutation {
   updatePromotion: Promotion;
   
   deletePromotion: DeletionResponse;
-  /** Create a new Role */
-  createRole: Role;
-  /** Update an existing Role */
-  updateRole: Role;
   /** Create a new ShippingMethod */
   createShippingMethod: ShippingMethod;
   /** Update an existing ShippingMethod */
   updateShippingMethod: ShippingMethod;
+  /** Create a new Role */
+  createRole: Role;
+  /** Update an existing Role */
+  updateRole: Role;
   /** Create a new TaxCategory */
   createTaxCategory: TaxCategory;
   /** Update an existing TaxCategory */
@@ -6036,10 +6040,6 @@ export interface CountryQueryArgs {
   
   id: string;
 }
-export interface CustomerGroupQueryArgs {
-  
-  id: string;
-}
 export interface CustomersQueryArgs {
   
   options?: Maybe<CustomerListOptions>;
@@ -6060,6 +6060,10 @@ export interface FacetQueryArgs {
   
   languageCode?: Maybe<LanguageCode>;
 }
+export interface CustomerGroupQueryArgs {
+  
+  id: string;
+}
 export interface OrderQueryArgs {
   
   id: string;
@@ -6112,19 +6116,19 @@ export interface PromotionsQueryArgs {
   
   options?: Maybe<PromotionListOptions>;
 }
-export interface RolesQueryArgs {
+export interface ShippingMethodsQueryArgs {
   
-  options?: Maybe<RoleListOptions>;
+  options?: Maybe<ShippingMethodListOptions>;
 }
-export interface RoleQueryArgs {
+export interface ShippingMethodQueryArgs {
   
   id: string;
 }
-export interface ShippingMethodsQueryArgs {
+export interface RolesQueryArgs {
   
-  options?: Maybe<ShippingMethodListOptions>;
+  options?: Maybe<RoleListOptions>;
 }
-export interface ShippingMethodQueryArgs {
+export interface RoleQueryArgs {
   
   id: string;
 }
@@ -6214,26 +6218,6 @@ export interface DeleteCountryMutationArgs {
   
   id: string;
 }
-export interface CreateCustomerGroupMutationArgs {
-  
-  input: CreateCustomerGroupInput;
-}
-export interface UpdateCustomerGroupMutationArgs {
-  
-  input: UpdateCustomerGroupInput;
-}
-export interface AddCustomersToGroupMutationArgs {
-  
-  customerGroupId: string;
-  
-  customerIds: string[];
-}
-export interface RemoveCustomersFromGroupMutationArgs {
-  
-  customerGroupId: string;
-  
-  customerIds: string[];
-}
 export interface CreateCustomerMutationArgs {
   
   input: CreateCustomerInput;
@@ -6290,6 +6274,26 @@ export interface DeleteFacetValuesMutationArgs {
   
   force?: Maybe<boolean>;
 }
+export interface CreateCustomerGroupMutationArgs {
+  
+  input: CreateCustomerGroupInput;
+}
+export interface UpdateCustomerGroupMutationArgs {
+  
+  input: UpdateCustomerGroupInput;
+}
+export interface AddCustomersToGroupMutationArgs {
+  
+  customerGroupId: string;
+  
+  customerIds: string[];
+}
+export interface RemoveCustomersFromGroupMutationArgs {
+  
+  customerGroupId: string;
+  
+  customerIds: string[];
+}
 export interface UpdateGlobalSettingsMutationArgs {
   
   input: UpdateGlobalSettingsInput;
@@ -6360,14 +6364,6 @@ export interface DeletePromotionMutationArgs {
   
   id: string;
 }
-export interface CreateRoleMutationArgs {
-  
-  input: CreateRoleInput;
-}
-export interface UpdateRoleMutationArgs {
-  
-  input: UpdateRoleInput;
-}
 export interface CreateShippingMethodMutationArgs {
   
   input: CreateShippingMethodInput;
@@ -6376,6 +6372,14 @@ export interface UpdateShippingMethodMutationArgs {
   
   input: UpdateShippingMethodInput;
 }
+export interface CreateRoleMutationArgs {
+  
+  input: CreateRoleInput;
+}
+export interface UpdateRoleMutationArgs {
+  
+  input: UpdateRoleInput;
+}
 export interface CreateTaxCategoryMutationArgs {
   
   input: CreateTaxCategoryInput;