Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 605 order summary details #615

Merged
merged 5 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/composables.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
```ts

import { AddressType } from '@shopware-pwa/commons/interfaces/models/checkout/customer/CustomerAddress';
import { BillingAddress } from '@shopware-pwa/commons/interfaces/request/GuestOrderParams';
import { Country } from '@shopware-pwa/commons/interfaces/models/system/country/Country';
import { Customer } from '@shopware-pwa/commons/interfaces/models/checkout/customer/Customer';
import { CustomerAddress } from '@shopware-pwa/commons/interfaces/models/checkout/customer/CustomerAddress';
Expand All @@ -20,6 +21,7 @@ import { Product } from '@shopware-pwa/commons/interfaces/models/content/product
import { Ref } from '@vue/composition-api';
import { Salutation } from '@shopware-pwa/commons/interfaces/models/system/salutation/Salutation';
import { SessionContext } from '@shopware-pwa/commons/interfaces/response/SessionContext';
import { ShippingAddress } from '@shopware-pwa/commons/interfaces/request/GuestOrderParams';
import { ShippingMethod } from '@shopware-pwa/commons/interfaces/models/checkout/shipping/ShippingMethod';

// @alpha (undocumented)
Expand Down Expand Up @@ -88,6 +90,8 @@ export const useCategoryFilters: () => any;

// @alpha (undocumented)
export interface UseCheckout {
// (undocumented)
billingAddress: Readonly<Ref<BillingAddress | undefined>>;
// (undocumented)
createOrder: () => Promise<Order>;
// (undocumented)
Expand All @@ -103,6 +107,8 @@ export interface UseCheckout {
// (undocumented)
isGuestOrder: Readonly<Ref<boolean>>;
// (undocumented)
shippingAddress: Readonly<Ref<ShippingAddress | undefined>>;
// (undocumented)
updateGuestOrderParams: (params: Partial<GuestOrderParams>) => void;
}

Expand Down
5 changes: 4 additions & 1 deletion packages/commons/interfaces/models/system/user/User.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export interface User {}
import { BillingAddress } from "../../../request/GuestOrderParams";
export interface User {
activeBillingAddress?: BillingAddress;
}
2 changes: 2 additions & 0 deletions packages/commons/interfaces/response/SessionContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { PaymentMethod } from "../models/checkout/payment/PaymentMethod";
import { ShippingMethod } from "../models/checkout/shipping/ShippingMethod";
import { Country } from "../models/system/country/Country";
import { User } from "../models/system/user/User";
import { ShippingAddress } from "../request/GuestOrderParams";

export interface ContextTokenResponse {
contextToken: string;
Expand Down Expand Up @@ -33,6 +34,7 @@ export interface SessionContext {
paymentMethod: PaymentMethod;
shippingMethod: ShippingMethod;
shippingLocation: {
address: ShippingAddress;
country: Country;
};
}
123 changes: 122 additions & 1 deletion packages/composables/__tests__/useCheckout.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import Vue from "vue";
import VueCompositionApi, { ref } from "@vue/composition-api";
import VueCompositionApi, {
ref,
Ref,
reactive,
computed,
} from "@vue/composition-api";
Vue.use(VueCompositionApi);

// // Mock API client
Expand All @@ -10,23 +15,36 @@ const mockedApiClient = shopwareClient as jest.Mocked<typeof shopwareClient>;
const consoleErrorSpy = jest.spyOn(console, "error");
import * as Composables from "@shopware-pwa/composables";
import { useCheckout } from "@shopware-pwa/composables";
import { SessionContext } from "@shopware-pwa/commons/interfaces/response/SessionContext";

describe("Composables - useCheckout", () => {
let isLoggedIn = ref(false);
const stateContext: Ref<Partial<SessionContext> | null> = ref(null);

const refreshCartMock = jest.fn(async () => {});
beforeEach(() => {
jest.resetAllMocks();
isLoggedIn.value = false;
jest.spyOn(Composables, "useUser").mockImplementation(() => {
return {
isLoggedIn,
user: ref({ firstName: "Elton" }),
} as any;
});
jest.spyOn(Composables, "useCart").mockImplementation(() => {
return {
refreshCart: refreshCartMock,
} as any;
});
stateContext.value = null;
Composables.setStore({
getters: reactive({
getSessionContext: computed(() => stateContext.value),
}),
commit: (name: string, value: SessionContext) => {
stateContext.value = value;
},
});
consoleErrorSpy.mockImplementationOnce(() => {});
});

Expand All @@ -51,6 +69,109 @@ describe("Composables - useCheckout", () => {
expect(guestOrderParams.value).toEqual({});
});
});

describe("shippingAddress", () => {
it("should return guest order address if is guest order", () => {
const { shippingAddress, updateGuestOrderParams } = useCheckout();
updateGuestOrderParams({
shippingAddress: {
street: "first street",
},
} as any);
expect(shippingAddress.value).toEqual({ street: "first street" });
updateGuestOrderParams({
shippingAddress: undefined,
} as any);
});

it("should undefined when guest address is not set", () => {
const { shippingAddress } = useCheckout();
expect(shippingAddress.value).toBeUndefined();
});

it("should return user address in case of user order", async () => {
isLoggedIn.value = true;
stateContext.value = {
shippingLocation: {
address: {
street: "some street",
},
},
} as any;
const { shippingAddress } = useCheckout();
expect(shippingAddress.value).toEqual({ street: "some street" });
});

it("should return undefined if address is not set", async () => {
isLoggedIn.value = true;
stateContext.value = {} as any;
const { shippingAddress } = useCheckout();
expect(shippingAddress.value).toBeUndefined();
});

it("should return undefined if no session context", async () => {
isLoggedIn.value = true;
stateContext.value = null as any;
const { shippingAddress } = useCheckout();
expect(shippingAddress.value).toBeUndefined();
});
});

describe("billingAddress", () => {
it("should return guest order address if is guest order", () => {
const { billingAddress, updateGuestOrderParams } = useCheckout();
updateGuestOrderParams({
billingAddress: {
street: "thrid street",
},
} as any);
expect(billingAddress.value).toEqual({ street: "thrid street" });
updateGuestOrderParams({
billingAddress: undefined,
} as any);
});

it("should return undefined when guest billing address is not set", () => {
const { billingAddress, updateGuestOrderParams } = useCheckout();
updateGuestOrderParams({
billingAddress: {
street: "thrid street",
},
} as any);
expect(billingAddress.value).toEqual({ street: "thrid street" });
updateGuestOrderParams({
billingAddress: undefined,
} as any);
});

it("should return address in case of user order", async () => {
isLoggedIn.value = true;
stateContext.value = {
customer: {
activeBillingAddress: {
street: "some street",
},
},
} as any;
const { billingAddress } = useCheckout();
await Vue.nextTick();
expect(billingAddress.value).toEqual({ street: "some street" });
});

it("should return undefined if address is not set", async () => {
isLoggedIn.value = true;
stateContext.value = {} as any;
const { billingAddress } = useCheckout();
expect(billingAddress.value).toBeUndefined();
});

it("should return undefined if no session context", async () => {
isLoggedIn.value = true;
stateContext.value = null as any;
const { billingAddress } = useCheckout();
expect(billingAddress.value).toBeUndefined();
});
});
});

describe("methods", () => {
Expand Down
24 changes: 23 additions & 1 deletion packages/composables/src/logic/useCheckout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ import { Ref, computed, reactive } from "@vue/composition-api";
import { useUser, useCart } from "@shopware-pwa/composables";
import { ShippingMethod } from "@shopware-pwa/commons/interfaces/models/checkout/shipping/ShippingMethod";
import { PaymentMethod } from "@shopware-pwa/commons/interfaces/models/checkout/payment/PaymentMethod";
import { GuestOrderParams } from "@shopware-pwa/commons/interfaces/request/GuestOrderParams";
import {
GuestOrderParams,
ShippingAddress,
BillingAddress,
} from "@shopware-pwa/commons/interfaces/request/GuestOrderParams";
import { Order } from "@shopware-pwa/commons/interfaces/models/checkout/order/Order";
import {
getAvailableShippingMethods,
getAvailablePaymentMethods,
createGuestOrder,
createOrder as createApiOrder,
} from "@shopware-pwa/shopware-6-client";
import { useSessionContext } from "./useSessionContext";

/**
* @alpha
Expand All @@ -26,6 +31,8 @@ export interface UseCheckout {
}) => Promise<Readonly<Ref<readonly PaymentMethod[]>>>;
createOrder: () => Promise<Order>;
updateGuestOrderParams: (params: Partial<GuestOrderParams>) => void;
shippingAddress: Readonly<Ref<ShippingAddress | undefined>>;
billingAddress: Readonly<Ref<BillingAddress | undefined>>;
}

const orderData: {
Expand All @@ -44,6 +51,8 @@ const orderData: {
export const useCheckout = (): UseCheckout => {
const { isLoggedIn } = useUser();
const { refreshCart } = useCart();
const { sessionContext } = useSessionContext();

const shippingMethods: Readonly<Ref<readonly ShippingMethod[]>> = computed(
() => orderData.shippingMethods
);
Expand Down Expand Up @@ -96,12 +105,25 @@ export const useCheckout = (): UseCheckout => {
orderData.guestOrderParams = { ...orderData.guestOrderParams, ...params };
};

const shippingAddress = computed(() =>
isGuestOrder.value
? guestOrderParams.value.shippingAddress
: sessionContext.value?.shippingLocation?.address
);
const billingAddress = computed(() =>
isGuestOrder.value
? guestOrderParams.value.billingAddress
: sessionContext.value?.customer?.activeBillingAddress
);

return {
isGuestOrder,
getPaymentMethods,
getShippingMethods,
createOrder,
guestOrderParams,
updateGuestOrderParams,
shippingAddress,
billingAddress,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
required
/>
<SfSelect
v-if="getCountries.length"
v-model="countryId"
:valid="!validations.countryId.$error"
error-message="This field is required"
Expand All @@ -81,11 +82,11 @@
required
>
<SfSelectOption
v-for="countryOption in countries"
:key="countryOption"
:value="countryOption"
v-for="countryOption in getCountries"
:key="countryOption.id"
:value="countryOption.id"
>
{{ countryOption }}
{{ countryOption.name }}
</SfSelectOption>
</SfSelect>
<SfInput
Expand Down Expand Up @@ -116,6 +117,7 @@ import {
usePaymentStepValidationRules,
} from '@shopware-pwa/default-theme/logic/checkout/usePaymentStep'
import { computed } from '@vue/composition-api'
import { useCountries } from '@shopware-pwa/composables'

export default {
name: 'BillingAddressGuestForm',
Expand Down Expand Up @@ -146,8 +148,7 @@ export default {
differentThanShipping,
} = usePaymentStep()

// TODO add countries
const countries = computed(() => [])
const { getCountries } = useCountries()

return {
validations,
Expand All @@ -162,7 +163,7 @@ export default {
countryId,
phoneNumber,
differentThanShipping,
countries
getCountries,
}
},
watch: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
<template>
<div class="accordion__item">
<div class="accordion__content">
<p v-if="billingAddress.sameAsShipping" class="content">
Same as shipping address
<p class="content" v-if="billingAddress">
{{ billingAddress.street }} {{ billingAddress.apartment }},
{{ billingAddress.zipcode }}<br />
{{ billingAddress.city }}
</p>
<p class="content" v-if="billingAddress && billingAddress.phoneNumber">
{{ billingAddress.phoneNumber }}
</p>
<template v-else>
<p class="content">
<span class="content__label">{{ billingAddress.shippingMethod }}</span
><br />
{{ billingAddress.streetName }} {{ billingAddress.apartment }}, {{ billingAddress.zipCode
}}<br />
{{ billingAddress.city }}, {{ billingAddress.country }}
</p>
<p class="content">{{ billingAddress.phoneNumber }}</p>
</template>
</div>
<SfButton
class="sf-button--text accordion__edit"
Expand All @@ -23,23 +18,20 @@
</div>
</template>
<script>
import {
SfButton
} from '@storefront-ui/vue'
import { SfButton } from '@storefront-ui/vue'
import { useCheckout } from '@shopware-pwa/composables'

export default {
name: 'BillingAddressSummary',
components: {
SfButton,
},
setup () {
// TODO: get from context or guest order step if guest order
const billingAddress = {
sameAsShipping: true
}
setup() {
const { billingAddress } = useCheckout()
return {
billingAddress
billingAddress,
}
}
},
}
</script>
<style lang="scss" scoped>
Expand Down
Loading