Skip to content

Commit

Permalink
Merge pull request #4556 from mirumee/add-voucher-settings
Browse files Browse the repository at this point in the history
Add voucher settings
  • Loading branch information
maarcingebala committed Jul 30, 2019
2 parents 94314bf + c25bbae commit ea758d5
Show file tree
Hide file tree
Showing 19 changed files with 965 additions and 265 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Do not lose focus while typing in product description field - #4549 by @dominik-zeglen
- Update JSON menu representation in mutations - #4524 by @maarcingebala
- Display menu item form errors - #4551 by @dominik-zeglen
- Add voucher settings - #4556 by @benekex2

## 2.8.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import i18n from "../../../i18n";
import { UserError } from "../../../types";
import {
DiscountValueTypeEnum,
RequirementsPickerEnum,
VoucherTypeEnum
} from "../../../types/globalTypes";
import VoucherDates from "../VoucherDates";
Expand All @@ -22,6 +23,7 @@ import VoucherTypes from "../VoucherTypes";

import VoucherValue from "../VoucherValue";
export interface FormData {
applyOncePerCustomer: boolean;
applyOncePerOrder: boolean;
code: string;
discountType: DiscountValueTypeEnum;
Expand All @@ -30,6 +32,8 @@ export interface FormData {
hasEndDate: boolean;
hasUsageLimit: boolean;
minAmountSpent: string;
minCheckoutItemsQuantity: string;
requirementsPicker: RequirementsPickerEnum;
startDate: string;
startTime: string;
type: VoucherTypeEnum;
Expand All @@ -55,6 +59,7 @@ const VoucherCreatePage: React.StatelessComponent<VoucherCreatePageProps> = ({
onSubmit
}) => {
const initialForm: FormData = {
applyOncePerCustomer: false,
applyOncePerOrder: false,
code: "",
discountType: DiscountValueTypeEnum.FIXED,
Expand All @@ -63,6 +68,8 @@ const VoucherCreatePage: React.StatelessComponent<VoucherCreatePageProps> = ({
hasEndDate: false,
hasUsageLimit: false,
minAmountSpent: "0",
minCheckoutItemsQuantity: "0",
requirementsPicker: RequirementsPickerEnum.NONE,
startDate: "",
startTime: "",
type: VoucherTypeEnum.ENTIRE_ORDER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { maybe, splitDateTime } from "../../../misc";
import { ListProps, TabListActions, UserError } from "../../../types";
import {
DiscountValueTypeEnum,
RequirementsPickerEnum,
VoucherTypeEnum
} from "../../../types/globalTypes";
import { VoucherDetails_voucher } from "../../types/VoucherDetails";
Expand All @@ -35,6 +36,7 @@ export enum VoucherDetailsPageTab {
collections = "collections",
products = "products"
}

export function voucherDetailsPageTab(tab: string): VoucherDetailsPageTab {
return tab === VoucherDetailsPageTab.products
? VoucherDetailsPageTab.products
Expand All @@ -44,6 +46,7 @@ export function voucherDetailsPageTab(tab: string): VoucherDetailsPageTab {
}

export interface FormData {
applyOncePerCustomer: boolean;
applyOncePerOrder: boolean;
code: string;
discountType: DiscountValueTypeEnum;
Expand All @@ -52,6 +55,8 @@ export interface FormData {
hasEndDate: boolean;
hasUsageLimit: boolean;
minAmountSpent: string;
minCheckoutItemsQuantity: string;
requirementsPicker: RequirementsPickerEnum;
startDate: string;
startTime: string;
type: VoucherTypeEnum;
Expand Down Expand Up @@ -123,7 +128,17 @@ const VoucherDetailsPage: React.StatelessComponent<VoucherDetailsPageProps> = ({
collectionListToolbar,
productListToolbar
}) => {
let requirementsPickerInitValue;
if (maybe(() => voucher.minAmountSpent.amount) > 0) {
requirementsPickerInitValue = RequirementsPickerEnum.ORDER;
} else if (maybe(() => voucher.minCheckoutItemsQuantity) > 0) {
requirementsPickerInitValue = RequirementsPickerEnum.ITEM;
} else {
requirementsPickerInitValue = RequirementsPickerEnum.NONE;
}

const initialForm: FormData = {
applyOncePerCustomer: maybe(() => voucher.applyOncePerCustomer, false),
applyOncePerOrder: maybe(() => voucher.applyOncePerOrder, false),
code: maybe(() => voucher.code, ""),
discountType: maybe(
Expand All @@ -135,6 +150,11 @@ const VoucherDetailsPage: React.StatelessComponent<VoucherDetailsPageProps> = ({
hasEndDate: maybe(() => !!voucher.endDate),
hasUsageLimit: maybe(() => !!voucher.usageLimit),
minAmountSpent: maybe(() => voucher.minAmountSpent.amount.toString(), "0"),
minCheckoutItemsQuantity: maybe(
() => voucher.minCheckoutItemsQuantity.toString(),
"0"
),
requirementsPicker: requirementsPickerInitValue,
startDate: splitDateTime(maybe(() => voucher.startDate, "")).date,
startTime: splitDateTime(maybe(() => voucher.startDate, "")).time,
type: maybe(() => voucher.type, VoucherTypeEnum.ENTIRE_ORDER),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ const VoucherLimits = ({
fullWidth
/>
)}
<ControlledCheckbox
checked={data.applyOncePerCustomer}
label={i18n.t("Limit to one use per customer")}
name={"applyOncePerCustomer" as keyof FormData}
onChange={onChange}
/>
</CardContent>
</Card>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import TextField from "@material-ui/core/TextField";
import * as React from "react";

import CardTitle from "@saleor/components/CardTitle";
import i18n from "../../../i18n";
import { FormErrors } from "../../../types";
import { FormSpacer } from "@saleor/components/FormSpacer";
import RadioGroupField from "@saleor/components/RadioGroupField";
import i18n from "@saleor/i18n";
import { FormErrors } from "@saleor/types";
import { RequirementsPickerEnum } from "../../../types/globalTypes";
import { FormData } from "../VoucherDetailsPage";

interface VoucherRequirementsProps {
data: FormData;
defaultCurrency: string;
disabled: boolean;
errors: FormErrors<"minAmountSpent">;
errors: FormErrors<"minAmountSpent" | "minCheckoutItemsQuantity">;
onChange: (event: React.ChangeEvent<any>) => void;
}

Expand All @@ -22,20 +25,56 @@ const VoucherRequirements = ({
errors,
onChange
}: VoucherRequirementsProps) => {
const requirementsPickerChoices = [
{
label: i18n.t("None"),
value: RequirementsPickerEnum.NONE
},
{
label: i18n.t("Minimal order value"),
value: RequirementsPickerEnum.ORDER
},
{
label: i18n.t("Minimum quantity of items"),
value: RequirementsPickerEnum.ITEM
}
];

return (
<Card>
<CardTitle title={i18n.t("Minimum Requirements")} />
<CardContent>
<TextField
<RadioGroupField
choices={requirementsPickerChoices}
disabled={disabled}
error={!!errors.minAmountSpent}
helperText={errors.minAmountSpent}
label={i18n.t("Minimal order value")}
name={"minAmountSpent" as keyof FormData}
value={data.minAmountSpent}
name={"requirementsPicker" as keyof FormData}
value={data.requirementsPicker}
onChange={onChange}
fullWidth
/>
<FormSpacer />
{data.requirementsPicker === RequirementsPickerEnum.ORDER ? (
<TextField
disabled={disabled}
error={!!errors.minAmountSpent}
helperText={errors.minAmountSpent}
label={i18n.t("Minimal order value")}
name={"minAmountSpent" as keyof FormData}
value={data.minAmountSpent}
onChange={onChange}
fullWidth
/>
) : data.requirementsPicker === RequirementsPickerEnum.ITEM ? (
<TextField
disabled={disabled}
error={!!errors.minCheckoutItemsQuantity}
helperText={errors.minCheckoutItemsQuantity}
label={i18n.t("Minimum quantity of items")}
name={"minCheckoutItemsQuantity" as keyof FormData}
value={data.minCheckoutItemsQuantity}
onChange={onChange}
fullWidth
/>
) : null}
</CardContent>
</Card>
);
Expand Down
4 changes: 4 additions & 0 deletions saleor/static/dashboard-next/discounts/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const voucherList: VoucherList_vouchers_edges_node[] = [
endDate: null,
id: "Vm91Y2hlcjox",
minAmountSpent: null,
minCheckoutItemsQuantity: null,
startDate: "2019-01-03",
usageLimit: null
},
Expand All @@ -89,6 +90,7 @@ export const voucherList: VoucherList_vouchers_edges_node[] = [
amount: 200,
currency: "USD"
},
minCheckoutItemsQuantity: 0,
startDate: "2019-01-03",
usageLimit: 150
}
Expand Down Expand Up @@ -241,6 +243,7 @@ export const sale: SaleDetails_sale = {

export const voucherDetails: VoucherDetails_voucher = {
__typename: "Voucher",
applyOncePerCustomer: false,
applyOncePerOrder: false,
categories: {
__typename: "CategoryCountableConnection",
Expand Down Expand Up @@ -283,6 +286,7 @@ export const voucherDetails: VoucherDetails_voucher = {
amount: 200,
currency: "USD"
},
minCheckoutItemsQuantity: 0,
products: {
__typename: "ProductCountableConnection",
edges: [],
Expand Down
2 changes: 2 additions & 0 deletions saleor/static/dashboard-next/discounts/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const voucherFragment = gql`
currency
amount
}
minCheckoutItemsQuantity
}
`;

Expand All @@ -108,6 +109,7 @@ export const voucherDetailsFragment = gql`
usageLimit
used
applyOncePerOrder
applyOncePerCustomer
products(after: $after, before: $before, first: $first, last: $last) {
edges {
node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,11 @@ export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher {
discountValue: number;
countries: (VoucherCataloguesAdd_voucherCataloguesAdd_voucher_countries | null)[] | null;
minAmountSpent: VoucherCataloguesAdd_voucherCataloguesAdd_voucher_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
type: VoucherTypeEnum;
used: number;
applyOncePerOrder: boolean;
applyOncePerCustomer: boolean;
products: VoucherCataloguesAdd_voucherCataloguesAdd_voucher_products | null;
collections: VoucherCataloguesAdd_voucherCataloguesAdd_voucher_collections | null;
categories: VoucherCataloguesAdd_voucherCataloguesAdd_voucher_categories | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,11 @@ export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher {
discountValue: number;
countries: (VoucherCataloguesRemove_voucherCataloguesRemove_voucher_countries | null)[] | null;
minAmountSpent: VoucherCataloguesRemove_voucherCataloguesRemove_voucher_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
type: VoucherTypeEnum;
used: number;
applyOncePerOrder: boolean;
applyOncePerCustomer: boolean;
products: VoucherCataloguesRemove_voucherCataloguesRemove_voucher_products | null;
collections: VoucherCataloguesRemove_voucherCataloguesRemove_voucher_collections | null;
categories: VoucherCataloguesRemove_voucherCataloguesRemove_voucher_categories | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface VoucherCreate_voucherCreate_voucher {
discountValue: number;
countries: (VoucherCreate_voucherCreate_voucher_countries | null)[] | null;
minAmountSpent: VoucherCreate_voucherCreate_voucher_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
}

export interface VoucherCreate_voucherCreate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,11 @@ export interface VoucherDetails_voucher {
discountValue: number;
countries: (VoucherDetails_voucher_countries | null)[] | null;
minAmountSpent: VoucherDetails_voucher_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
type: VoucherTypeEnum;
used: number;
applyOncePerOrder: boolean;
applyOncePerCustomer: boolean;
products: VoucherDetails_voucher_products | null;
collections: VoucherDetails_voucher_collections | null;
categories: VoucherDetails_voucher_categories | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,11 @@ export interface VoucherDetailsFragment {
discountValue: number;
countries: (VoucherDetailsFragment_countries | null)[] | null;
minAmountSpent: VoucherDetailsFragment_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
type: VoucherTypeEnum;
used: number;
applyOncePerOrder: boolean;
applyOncePerCustomer: boolean;
products: VoucherDetailsFragment_products | null;
collections: VoucherDetailsFragment_collections | null;
categories: VoucherDetailsFragment_categories | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ export interface VoucherFragment {
discountValue: number;
countries: (VoucherFragment_countries | null)[] | null;
minAmountSpent: VoucherFragment_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface VoucherList_vouchers_edges_node {
discountValue: number;
countries: (VoucherList_vouchers_edges_node_countries | null)[] | null;
minAmountSpent: VoucherList_vouchers_edges_node_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
}

export interface VoucherList_vouchers_edges {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface VoucherUpdate_voucherUpdate_voucher {
discountValue: number;
countries: (VoucherUpdate_voucherUpdate_voucher_countries | null)[] | null;
minAmountSpent: VoucherUpdate_voucherUpdate_voucher_minAmountSpent | null;
minCheckoutItemsQuantity: number | null;
}

export interface VoucherUpdate_voucherUpdate {
Expand Down
13 changes: 12 additions & 1 deletion saleor/static/dashboard-next/discounts/views/VoucherCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import i18n from "../../i18n";
import { decimal, getMutationState, joinDateTime, maybe } from "../../misc";
import {
DiscountValueTypeEnum,
RequirementsPickerEnum,
VoucherTypeEnum
} from "../../types/globalTypes";
import VoucherCreatePage from "../components/VoucherCreatePage";
Expand Down Expand Up @@ -52,6 +53,7 @@ export const VoucherDetails: React.StatelessComponent = () => {
voucherCreate({
variables: {
input: {
applyOncePerCustomer: formData.applyOncePerCustomer,
applyOncePerOrder: formData.applyOncePerOrder,
code: formData.code,
discountValue:
Expand All @@ -65,7 +67,16 @@ export const VoucherDetails: React.StatelessComponent = () => {
endDate: formData.hasEndDate
? joinDateTime(formData.endDate, formData.endTime)
: null,
minAmountSpent: parseFloat(formData.minAmountSpent),
minAmountSpent:
formData.requirementsPicker !==
RequirementsPickerEnum.ORDER
? 0
: parseFloat(formData.minAmountSpent),
minCheckoutItemsQuantity:
formData.requirementsPicker !==
RequirementsPickerEnum.ITEM
? 0
: parseFloat(formData.minCheckoutItemsQuantity),
startDate: joinDateTime(
formData.startDate,
formData.startTime
Expand Down

0 comments on commit ea758d5

Please sign in to comment.