@zenky/storefront-vue 0.9.38 → 0.9.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +1392 -26
- package/dist/esm/index.js +1348 -5
- package/dist/zenky.d.ts +9050 -3
- package/package.json +3 -2
package/dist/esm/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ref, computed, watch, unref, inject } from 'vue';
|
|
2
|
-
import { debounce, isBoolean } from 'lodash-es';
|
|
3
|
-
import { getStore, getAddressSuggestions, getCategoriesTree, Visibility, getProductsCollections, getApiErrorMessage, getCategoryFeatures, getCategoryFeaturesGroups, getArticles, getArticleCategories,
|
|
4
|
-
import { defineStore } from 'pinia';
|
|
2
|
+
import { debounce, isBoolean, cloneDeep } from 'lodash-es';
|
|
3
|
+
import { getStore, getAddressSuggestions, getCategoriesTree, Visibility, getProductsCollections, getApiErrorMessage, getCategoryFeatures, getCategoryFeaturesGroups, getArticle, getArticles, getArticleCategories, getAuthenticationStatus, setAxiosToken, getCustomerProfile, login, requestPasswordResetCode, resetPassword, register, resendConfirmationCode, confirm, getApiErrorCode, getCustomerAddresses, deleteAddress, updateAddress, getOrder, getCustomerOrders, getCustomerPaymentMethods, deleteCustomerPaymentMethod, ImageType, getOffer, getOffers, setOrderCheckoutCustomer, getOrderSettings, createOrder, addOrderProductVariant, removeOrderProductVariant, confirmOrder, resendOrderConfirmationCode, setOrderCheckoutDelivery, setOrderCheckoutPayment, getOrderBonusesPaymentPreview, checkoutOrder, getOrderCheckoutTotal, getProductVariantPrice, getProduct, getProductsPricesRange, getProducts, checkCompletedPromotions } from '@zenky/api';
|
|
4
|
+
import { defineStore, storeToRefs } from 'pinia';
|
|
5
5
|
import { useNotification } from '@zenky/ui';
|
|
6
|
-
import { useCustomerLoaded, useCustomerAuthenticated, useCustomerLoggedOut, usePromotionsCheckerStarted, usePromotionsCheckerCompleted, useDisplayOrderPromotionRewardSelection, useOrderPromotionsNotFound,
|
|
6
|
+
import { useCustomerLoaded, useCustomerAuthenticated, useCustomerLoggedOut, useOrderLoaded, useProductQuantityIncreased, useProductQuantityDecreased, usePromotionsCheckerStarted, usePromotionsCheckerCompleted, useDisplayOrderPromotionRewardSelection, useOrderPromotionsNotFound, useOrderPriceRecalculated, useOrderShouldBeReloaded, useOrderPromotionRewardsShouldBeReloaded, useOrderSubmitted } from '@zenky/events';
|
|
7
|
+
import { format } from 'date-fns';
|
|
7
8
|
import Pusher from 'pusher-js';
|
|
8
9
|
|
|
9
10
|
function useDataDestroyer(destroyer, errorHandler) {
|
|
@@ -1548,6 +1549,1348 @@ function useOfferItem(errorHandler) {
|
|
|
1548
1549
|
}));
|
|
1549
1550
|
}
|
|
1550
1551
|
|
|
1552
|
+
function getUpdatedVariants(currentOrder, order) {
|
|
1553
|
+
var _a, _b;
|
|
1554
|
+
if (!((_a = order === null || order === void 0 ? void 0 : order.variants) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
1555
|
+
return [];
|
|
1556
|
+
}
|
|
1557
|
+
else if (!((_b = currentOrder === null || currentOrder === void 0 ? void 0 : currentOrder.variants) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
1558
|
+
return (order === null || order === void 0 ? void 0 : order.variants) || [];
|
|
1559
|
+
}
|
|
1560
|
+
let current = cloneDeep(currentOrder.variants);
|
|
1561
|
+
let currentVariants = [];
|
|
1562
|
+
const currentlyHasVariants = current && current.length > 0;
|
|
1563
|
+
if (currentlyHasVariants) {
|
|
1564
|
+
currentVariants = current.map((variant) => variant.uuid);
|
|
1565
|
+
}
|
|
1566
|
+
const actualVariantIds = order.variants.map((variant) => variant.uuid);
|
|
1567
|
+
const createdVariantIds = order.variants
|
|
1568
|
+
.filter((variant) => currentVariants.indexOf(variant.uuid) === -1)
|
|
1569
|
+
.map((variant) => variant.uuid);
|
|
1570
|
+
if (currentlyHasVariants) {
|
|
1571
|
+
current = current.filter((variant) => actualVariantIds.indexOf(variant.uuid) !== -1);
|
|
1572
|
+
}
|
|
1573
|
+
if (createdVariantIds.length > 0) {
|
|
1574
|
+
current = current || [];
|
|
1575
|
+
order.variants.filter((variant) => createdVariantIds.indexOf(variant.uuid) !== -1)
|
|
1576
|
+
.forEach((variant) => current.push(variant));
|
|
1577
|
+
}
|
|
1578
|
+
order.variants.forEach((variant) => {
|
|
1579
|
+
const index = current.findIndex((item) => item.uuid === variant.uuid);
|
|
1580
|
+
if (index === -1) {
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
current[index].quantity = variant.quantity;
|
|
1584
|
+
current[index].original_total_price = variant.original_total_price;
|
|
1585
|
+
current[index].total_price = variant.total_price;
|
|
1586
|
+
current[index].discount_difference = variant.discount_difference;
|
|
1587
|
+
current[index].has_discount = variant.has_discount;
|
|
1588
|
+
});
|
|
1589
|
+
return current;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
function initializeOrderCustomer(credentialsResolver) {
|
|
1593
|
+
useCustomerAuthenticated().subscribe('order.customer.initialize', async ({ customer }) => {
|
|
1594
|
+
const credentials = credentialsResolver();
|
|
1595
|
+
if (credentials === null) {
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1598
|
+
try {
|
|
1599
|
+
await setOrderCheckoutCustomer(credentials, {
|
|
1600
|
+
phone: {
|
|
1601
|
+
number: customer.phone.e164,
|
|
1602
|
+
country: customer.phone.country,
|
|
1603
|
+
},
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
catch (e) {
|
|
1607
|
+
console.error('[orders/customer] Unable to attach customer to order.', { e });
|
|
1608
|
+
}
|
|
1609
|
+
});
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
const useOrderStore = defineStore({
|
|
1613
|
+
id: 'zenky:storefront:order',
|
|
1614
|
+
state: () => ({
|
|
1615
|
+
order: null,
|
|
1616
|
+
token: null,
|
|
1617
|
+
loading: false,
|
|
1618
|
+
inclusions: null,
|
|
1619
|
+
orderSettings: {
|
|
1620
|
+
loaded: false,
|
|
1621
|
+
loading: false,
|
|
1622
|
+
settings: null,
|
|
1623
|
+
},
|
|
1624
|
+
}),
|
|
1625
|
+
getters: {
|
|
1626
|
+
credentials() {
|
|
1627
|
+
if (!this.order || !this.order.id || this.token === null) {
|
|
1628
|
+
return null;
|
|
1629
|
+
}
|
|
1630
|
+
return {
|
|
1631
|
+
id: this.order.id,
|
|
1632
|
+
token: this.token,
|
|
1633
|
+
};
|
|
1634
|
+
},
|
|
1635
|
+
settings() {
|
|
1636
|
+
return this.orderSettings.settings;
|
|
1637
|
+
},
|
|
1638
|
+
settingsLoaded() {
|
|
1639
|
+
return this.orderSettings.loaded;
|
|
1640
|
+
},
|
|
1641
|
+
},
|
|
1642
|
+
actions: {
|
|
1643
|
+
async initialize(storeId, cityId, inclusions) {
|
|
1644
|
+
this.inclusions = inclusions;
|
|
1645
|
+
const storage = getStorage();
|
|
1646
|
+
const orderId = storage.get('order.id');
|
|
1647
|
+
const orderToken = storage.get('order.token');
|
|
1648
|
+
initializeOrderCustomer(() => this.credentials);
|
|
1649
|
+
this.loading = true;
|
|
1650
|
+
if (orderId && orderToken) {
|
|
1651
|
+
return this.load(storeId, cityId, orderId, orderToken);
|
|
1652
|
+
}
|
|
1653
|
+
return this.create(storeId, cityId);
|
|
1654
|
+
},
|
|
1655
|
+
async load(storeId, cityId, orderId, token) {
|
|
1656
|
+
var _a, _b, _c;
|
|
1657
|
+
const { item, load } = useOrderItem();
|
|
1658
|
+
await load({ id: orderId, token }, this.inclusions !== null ? { with: this.inclusions.order } : {});
|
|
1659
|
+
if (((_c = (_b = (_a = item.value) === null || _a === void 0 ? void 0 : _a.current_status) === null || _b === void 0 ? void 0 : _b.status) === null || _c === void 0 ? void 0 : _c.kind.id) === 'pending') {
|
|
1660
|
+
this.order = item.value;
|
|
1661
|
+
this.token = item.value.token;
|
|
1662
|
+
this.loading = false;
|
|
1663
|
+
useOrderLoaded().publish(this.order);
|
|
1664
|
+
await this.loadSettings();
|
|
1665
|
+
return true;
|
|
1666
|
+
}
|
|
1667
|
+
return this.create(storeId, cityId);
|
|
1668
|
+
},
|
|
1669
|
+
async loadSettings() {
|
|
1670
|
+
if (this.orderSettings.loading) {
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
else if (!this.credentials || !this.order || !this.order.city_id) {
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1676
|
+
this.orderSettings.loading = true;
|
|
1677
|
+
try {
|
|
1678
|
+
this.orderSettings.settings = await getOrderSettings(this.credentials, this.order.city_id);
|
|
1679
|
+
}
|
|
1680
|
+
catch (e) {
|
|
1681
|
+
console.error('[storefront/order] Unable to load order settings.', { e });
|
|
1682
|
+
}
|
|
1683
|
+
finally {
|
|
1684
|
+
this.orderSettings.loading = false;
|
|
1685
|
+
this.orderSettings.loaded = true;
|
|
1686
|
+
}
|
|
1687
|
+
},
|
|
1688
|
+
async create(storeId, cityId) {
|
|
1689
|
+
try {
|
|
1690
|
+
const order = await createOrder({ city_id: cityId });
|
|
1691
|
+
const storage = getStorage();
|
|
1692
|
+
storage.set('order.id', order.id);
|
|
1693
|
+
storage.set('order.token', order.token);
|
|
1694
|
+
return await this.load(storeId, cityId, order.id, order.token);
|
|
1695
|
+
}
|
|
1696
|
+
catch (e) {
|
|
1697
|
+
useNotification('error', 'Ошибка инициализации заказа', 'Не удалось инициализировать заказ. Обновите страницу.');
|
|
1698
|
+
}
|
|
1699
|
+
return false;
|
|
1700
|
+
},
|
|
1701
|
+
reset() {
|
|
1702
|
+
const storage = getStorage();
|
|
1703
|
+
storage.delete('order.id');
|
|
1704
|
+
storage.delete('order.token');
|
|
1705
|
+
},
|
|
1706
|
+
async add(productVariantId, quantity, modifiers = [], promotion = null) {
|
|
1707
|
+
if (!this.credentials) {
|
|
1708
|
+
throw new Error('Order is not yet initialized.');
|
|
1709
|
+
}
|
|
1710
|
+
try {
|
|
1711
|
+
const params = {
|
|
1712
|
+
quantity,
|
|
1713
|
+
modifiers,
|
|
1714
|
+
product_variant_id: productVariantId,
|
|
1715
|
+
};
|
|
1716
|
+
if (promotion && promotion.id && promotion.reward_id) {
|
|
1717
|
+
params.promotion_id = promotion.id;
|
|
1718
|
+
params.promotion_reward_id = promotion.reward_id;
|
|
1719
|
+
}
|
|
1720
|
+
const order = await addOrderProductVariant(this.credentials, params, this.inclusions !== null ? { with: this.inclusions.product } : {});
|
|
1721
|
+
useProductQuantityIncreased().publish({
|
|
1722
|
+
order,
|
|
1723
|
+
productVariantId,
|
|
1724
|
+
quantity,
|
|
1725
|
+
modifiers,
|
|
1726
|
+
promotion,
|
|
1727
|
+
});
|
|
1728
|
+
this.update(order);
|
|
1729
|
+
return true;
|
|
1730
|
+
}
|
|
1731
|
+
catch (e) {
|
|
1732
|
+
useNotification('error', 'Товар не добавлен', getApiErrorMessage(e, 'Не удалось добавить товар в корзину. Повторите попытку'));
|
|
1733
|
+
}
|
|
1734
|
+
return false;
|
|
1735
|
+
},
|
|
1736
|
+
async remove(productVariantId, quantity, modifiers = [], promotion = null) {
|
|
1737
|
+
if (!this.credentials) {
|
|
1738
|
+
throw new Error('Order is not yet initialized.');
|
|
1739
|
+
}
|
|
1740
|
+
try {
|
|
1741
|
+
const params = {
|
|
1742
|
+
quantity,
|
|
1743
|
+
modifiers,
|
|
1744
|
+
product_variant_id: productVariantId,
|
|
1745
|
+
};
|
|
1746
|
+
if (promotion && promotion.id && promotion.reward_id) {
|
|
1747
|
+
params.promotion_id = promotion.id;
|
|
1748
|
+
params.promotion_reward_id = promotion.reward_id;
|
|
1749
|
+
}
|
|
1750
|
+
const order = await removeOrderProductVariant(this.credentials, params, this.inclusions !== null ? { with: this.inclusions.product } : {});
|
|
1751
|
+
useProductQuantityDecreased().publish({
|
|
1752
|
+
order,
|
|
1753
|
+
productVariantId,
|
|
1754
|
+
quantity,
|
|
1755
|
+
modifiers,
|
|
1756
|
+
promotion,
|
|
1757
|
+
});
|
|
1758
|
+
this.update(order);
|
|
1759
|
+
return true;
|
|
1760
|
+
}
|
|
1761
|
+
catch (e) {
|
|
1762
|
+
useNotification('error', 'Товар не удалён', getApiErrorMessage(e, 'Не удалось удалить товар из корзины. Повторите попытку'));
|
|
1763
|
+
}
|
|
1764
|
+
return false;
|
|
1765
|
+
},
|
|
1766
|
+
update(order) {
|
|
1767
|
+
if (this.order === null) {
|
|
1768
|
+
this.order = order;
|
|
1769
|
+
return;
|
|
1770
|
+
}
|
|
1771
|
+
this.order.total_price = order.total_price;
|
|
1772
|
+
this.order.original_total_price = order.original_total_price;
|
|
1773
|
+
this.order.discount_difference = order.discount_difference;
|
|
1774
|
+
this.order.has_discount = order.has_discount;
|
|
1775
|
+
this.order.variants = getUpdatedVariants(this.order, order);
|
|
1776
|
+
},
|
|
1777
|
+
async recreate(storeId, cityId, inclusions = null) {
|
|
1778
|
+
this.reset();
|
|
1779
|
+
if (!this.inclusions && inclusions) {
|
|
1780
|
+
this.inclusions = inclusions;
|
|
1781
|
+
}
|
|
1782
|
+
this.loading = true;
|
|
1783
|
+
return this.create(storeId, cityId);
|
|
1784
|
+
},
|
|
1785
|
+
},
|
|
1786
|
+
});
|
|
1787
|
+
|
|
1788
|
+
function useStageDetectors(order) {
|
|
1789
|
+
const hasCustomer = () => !!order.customer && !!order.customer.id;
|
|
1790
|
+
const hasDelivery = () => {
|
|
1791
|
+
var _a;
|
|
1792
|
+
if (['pickup', 'on_premise'].indexOf(order.delivery_method.id) > -1) {
|
|
1793
|
+
return !!order.stock && !!order.stock.id;
|
|
1794
|
+
}
|
|
1795
|
+
return !!(order === null || order === void 0 ? void 0 : order.delivery_address) && !!((_a = order === null || order === void 0 ? void 0 : order.delivery_address) === null || _a === void 0 ? void 0 : _a.id);
|
|
1796
|
+
};
|
|
1797
|
+
return {
|
|
1798
|
+
hasCustomer,
|
|
1799
|
+
hasDelivery,
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
var CheckoutStage;
|
|
1803
|
+
(function (CheckoutStage) {
|
|
1804
|
+
CheckoutStage["Customer"] = "customer";
|
|
1805
|
+
CheckoutStage["Delivery"] = "delivery";
|
|
1806
|
+
CheckoutStage["Payments"] = "payments";
|
|
1807
|
+
CheckoutStage["Summary"] = "summary";
|
|
1808
|
+
})(CheckoutStage || (CheckoutStage = {}));
|
|
1809
|
+
function useOrderCheckout() {
|
|
1810
|
+
const currentStage = ref(CheckoutStage.Customer);
|
|
1811
|
+
const stages = ref({
|
|
1812
|
+
[CheckoutStage.Customer]: {
|
|
1813
|
+
active: false,
|
|
1814
|
+
completed: false,
|
|
1815
|
+
},
|
|
1816
|
+
[CheckoutStage.Delivery]: {
|
|
1817
|
+
active: false,
|
|
1818
|
+
completed: false,
|
|
1819
|
+
},
|
|
1820
|
+
[CheckoutStage.Payments]: {
|
|
1821
|
+
active: false,
|
|
1822
|
+
completed: false,
|
|
1823
|
+
},
|
|
1824
|
+
[CheckoutStage.Summary]: {
|
|
1825
|
+
active: false,
|
|
1826
|
+
completed: false,
|
|
1827
|
+
},
|
|
1828
|
+
});
|
|
1829
|
+
const { order, settingsLoaded } = storeToRefs(useOrderStore());
|
|
1830
|
+
const { loaded: customerLoaded } = storeToRefs(useCustomerStore());
|
|
1831
|
+
const ready = computed(() => {
|
|
1832
|
+
if (!order.value || !order.value.id || !order.value.token) {
|
|
1833
|
+
return false;
|
|
1834
|
+
}
|
|
1835
|
+
else if (!customerLoaded.value) {
|
|
1836
|
+
return false;
|
|
1837
|
+
}
|
|
1838
|
+
else if (!settingsLoaded.value) {
|
|
1839
|
+
return false;
|
|
1840
|
+
}
|
|
1841
|
+
return true;
|
|
1842
|
+
});
|
|
1843
|
+
const setStage = (newStage) => {
|
|
1844
|
+
currentStage.value = newStage;
|
|
1845
|
+
Object.keys(stages.value).forEach((key) => {
|
|
1846
|
+
stages.value[key].active = false;
|
|
1847
|
+
stages.value[key].completed = false;
|
|
1848
|
+
});
|
|
1849
|
+
stages.value[newStage].active = true;
|
|
1850
|
+
switch (newStage) {
|
|
1851
|
+
case CheckoutStage.Customer:
|
|
1852
|
+
break;
|
|
1853
|
+
case CheckoutStage.Delivery:
|
|
1854
|
+
stages.value.customer.completed = true;
|
|
1855
|
+
break;
|
|
1856
|
+
case CheckoutStage.Payments:
|
|
1857
|
+
stages.value.customer.completed = true;
|
|
1858
|
+
stages.value.delivery.completed = true;
|
|
1859
|
+
break;
|
|
1860
|
+
case CheckoutStage.Summary:
|
|
1861
|
+
stages.value.customer.completed = true;
|
|
1862
|
+
stages.value.delivery.completed = true;
|
|
1863
|
+
stages.value.payments.completed = true;
|
|
1864
|
+
break;
|
|
1865
|
+
default:
|
|
1866
|
+
console.error(`[checkout] Unknown stage provided: "${newStage}", resetting to customer stage.`);
|
|
1867
|
+
stages.value.customer.completed = false;
|
|
1868
|
+
stages.value.delivery.completed = false;
|
|
1869
|
+
stages.value.payments.completed = false;
|
|
1870
|
+
break;
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
watch(ready, () => {
|
|
1874
|
+
if (!ready.value || order.value === null) {
|
|
1875
|
+
return setStage(CheckoutStage.Customer);
|
|
1876
|
+
}
|
|
1877
|
+
const detectors = useStageDetectors(order.value);
|
|
1878
|
+
if (!detectors.hasCustomer()) {
|
|
1879
|
+
return setStage(CheckoutStage.Customer);
|
|
1880
|
+
}
|
|
1881
|
+
else if (!detectors.hasDelivery()) {
|
|
1882
|
+
return setStage(CheckoutStage.Delivery);
|
|
1883
|
+
}
|
|
1884
|
+
return setStage(CheckoutStage.Payments);
|
|
1885
|
+
}, { immediate: true });
|
|
1886
|
+
return {
|
|
1887
|
+
ready,
|
|
1888
|
+
order,
|
|
1889
|
+
stages,
|
|
1890
|
+
currentStage,
|
|
1891
|
+
setStage,
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
function useCheckoutConfirmation(order) {
|
|
1896
|
+
const form = ref({ code: '' });
|
|
1897
|
+
const confirming = ref(false);
|
|
1898
|
+
const resending = ref(false);
|
|
1899
|
+
const credentials = computed(() => ({
|
|
1900
|
+
id: order.value.id,
|
|
1901
|
+
token: order.value.token,
|
|
1902
|
+
}));
|
|
1903
|
+
const confirm = async () => {
|
|
1904
|
+
if (confirming.value) {
|
|
1905
|
+
return null;
|
|
1906
|
+
}
|
|
1907
|
+
else if (!form.value.code) {
|
|
1908
|
+
useNotification('error', 'Ошибка', 'Нужно указать код из SMS.');
|
|
1909
|
+
return null;
|
|
1910
|
+
}
|
|
1911
|
+
confirming.value = true;
|
|
1912
|
+
try {
|
|
1913
|
+
return await confirmOrder(credentials.value, form.value);
|
|
1914
|
+
}
|
|
1915
|
+
catch (e) {
|
|
1916
|
+
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось подтвердить заказ.'));
|
|
1917
|
+
}
|
|
1918
|
+
finally {
|
|
1919
|
+
confirming.value = false;
|
|
1920
|
+
}
|
|
1921
|
+
return null;
|
|
1922
|
+
};
|
|
1923
|
+
const resendCode = async () => {
|
|
1924
|
+
if (resending.value) {
|
|
1925
|
+
return;
|
|
1926
|
+
}
|
|
1927
|
+
resending.value = true;
|
|
1928
|
+
try {
|
|
1929
|
+
const result = await resendOrderConfirmationCode(credentials.value);
|
|
1930
|
+
if (result.success) {
|
|
1931
|
+
useNotification('success', 'Код выслан', 'Код был повторно выслан на ваш телефон.');
|
|
1932
|
+
}
|
|
1933
|
+
else {
|
|
1934
|
+
useNotification('error', 'Ошибка', 'Не удалось выслать код подтверждения. Повторите попытку позднее.');
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
catch (e) {
|
|
1938
|
+
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось выслать код подтверждения.'));
|
|
1939
|
+
}
|
|
1940
|
+
finally {
|
|
1941
|
+
resending.value = false;
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
return {
|
|
1945
|
+
form,
|
|
1946
|
+
confirming,
|
|
1947
|
+
confirm,
|
|
1948
|
+
resending,
|
|
1949
|
+
resendCode,
|
|
1950
|
+
};
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
function useCustomerCheckoutForm(emit) {
|
|
1954
|
+
var _a;
|
|
1955
|
+
const ready = ref(false);
|
|
1956
|
+
const saving = ref(false);
|
|
1957
|
+
const form = ref({
|
|
1958
|
+
phone: {
|
|
1959
|
+
number: '',
|
|
1960
|
+
country: 'RU',
|
|
1961
|
+
},
|
|
1962
|
+
first_name: '',
|
|
1963
|
+
last_name: '',
|
|
1964
|
+
});
|
|
1965
|
+
const { customer } = storeToRefs(useCustomerStore());
|
|
1966
|
+
const { order, credentials } = storeToRefs(useOrderStore());
|
|
1967
|
+
if (((_a = order.value) === null || _a === void 0 ? void 0 : _a.customer) && order.value.customer.id) {
|
|
1968
|
+
form.value.phone.number = order.value.customer.phone.national;
|
|
1969
|
+
form.value.phone.country = order.value.customer.phone.country;
|
|
1970
|
+
form.value.first_name = order.value.customer.first_name || '';
|
|
1971
|
+
form.value.last_name = order.value.customer.last_name || '';
|
|
1972
|
+
}
|
|
1973
|
+
else if (customer.value && customer.value.id) {
|
|
1974
|
+
form.value.phone.number = customer.value.phone.national;
|
|
1975
|
+
form.value.phone.country = customer.value.phone.country;
|
|
1976
|
+
form.value.first_name = customer.value.first_name || '';
|
|
1977
|
+
form.value.last_name = customer.value.last_name || '';
|
|
1978
|
+
}
|
|
1979
|
+
const save = async () => {
|
|
1980
|
+
if (!credentials.value) {
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
else if (saving.value) {
|
|
1984
|
+
return;
|
|
1985
|
+
}
|
|
1986
|
+
else if (!form.value.phone.number || !form.value.phone.country) {
|
|
1987
|
+
useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
|
|
1988
|
+
return;
|
|
1989
|
+
}
|
|
1990
|
+
else if (!form.value.first_name) {
|
|
1991
|
+
useNotification('error', 'Ошибка', 'Нужно указать имя.');
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1994
|
+
saving.value = true;
|
|
1995
|
+
try {
|
|
1996
|
+
await setOrderCheckoutCustomer(credentials.value, form.value);
|
|
1997
|
+
emit('completed');
|
|
1998
|
+
}
|
|
1999
|
+
catch (e) {
|
|
2000
|
+
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось сохранить контактные данные.'));
|
|
2001
|
+
}
|
|
2002
|
+
finally {
|
|
2003
|
+
saving.value = false;
|
|
2004
|
+
}
|
|
2005
|
+
};
|
|
2006
|
+
return {
|
|
2007
|
+
ready,
|
|
2008
|
+
saving,
|
|
2009
|
+
customer,
|
|
2010
|
+
form,
|
|
2011
|
+
save,
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
function useTotalPrice() {
|
|
2016
|
+
const { order } = storeToRefs(useOrderStore());
|
|
2017
|
+
return {
|
|
2018
|
+
totalPrice: computed(() => { var _a; return (_a = order.value) === null || _a === void 0 ? void 0 : _a.total_price; }),
|
|
2019
|
+
originalTotalPrice: computed(() => { var _a; return (_a = order.value) === null || _a === void 0 ? void 0 : _a.original_total_price; }),
|
|
2020
|
+
hasDiscount: computed(() => { var _a; return (_a = order.value) === null || _a === void 0 ? void 0 : _a.has_discount; }),
|
|
2021
|
+
discountDifference: computed(() => { var _a; return (_a = order.value) === null || _a === void 0 ? void 0 : _a.discount_difference; }),
|
|
2022
|
+
};
|
|
2023
|
+
}
|
|
2024
|
+
function useTotalQuantity() {
|
|
2025
|
+
const { order } = storeToRefs(useOrderStore());
|
|
2026
|
+
const quantity = computed(() => {
|
|
2027
|
+
var _a;
|
|
2028
|
+
if (!order.value) {
|
|
2029
|
+
return 0;
|
|
2030
|
+
}
|
|
2031
|
+
return (((_a = order.value) === null || _a === void 0 ? void 0 : _a.variants) || [])
|
|
2032
|
+
.map((variant) => variant.quantity)
|
|
2033
|
+
.reduce((variantQuantity, total) => variantQuantity + total, 0);
|
|
2034
|
+
});
|
|
2035
|
+
return {
|
|
2036
|
+
order,
|
|
2037
|
+
quantity,
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
function useOrderVariants() {
|
|
2041
|
+
const { order } = storeToRefs(useOrderStore());
|
|
2042
|
+
const variants = computed(() => {
|
|
2043
|
+
if (!order.value || !order.value.variants || !order.value.variants.length) {
|
|
2044
|
+
return [];
|
|
2045
|
+
}
|
|
2046
|
+
return order.value.variants;
|
|
2047
|
+
});
|
|
2048
|
+
return {
|
|
2049
|
+
variants,
|
|
2050
|
+
};
|
|
2051
|
+
}
|
|
2052
|
+
const useVariantControls = (variant, modifiers, modifiersHash, promotion) => {
|
|
2053
|
+
const { order } = storeToRefs(useOrderStore());
|
|
2054
|
+
const { add: addVariant, remove: removeVariant } = useOrderStore();
|
|
2055
|
+
const loading = ref(false);
|
|
2056
|
+
const operation = ref(null);
|
|
2057
|
+
const orderVariant = computed(() => {
|
|
2058
|
+
var _a, _b;
|
|
2059
|
+
if (!((_b = (_a = order.value) === null || _a === void 0 ? void 0 : _a.variants) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
2060
|
+
return null;
|
|
2061
|
+
}
|
|
2062
|
+
return order.value.variants.find((item) => {
|
|
2063
|
+
if (item.product_variant_id !== variant.value.id || item.modifiers_hash !== modifiersHash.value) {
|
|
2064
|
+
return false;
|
|
2065
|
+
}
|
|
2066
|
+
else if (promotion.value === null) {
|
|
2067
|
+
return item.promotion_id === null;
|
|
2068
|
+
}
|
|
2069
|
+
return item.promotion_id === promotion.value.id && item.promotion_reward_id === promotion.value.reward_id;
|
|
2070
|
+
});
|
|
2071
|
+
});
|
|
2072
|
+
const totalQuantity = computed(() => (orderVariant.value ? orderVariant.value.quantity : 0));
|
|
2073
|
+
const quantityModel = ref(totalQuantity.value);
|
|
2074
|
+
const updateVariant = async (type, quantity) => {
|
|
2075
|
+
if (loading.value) {
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
loading.value = true;
|
|
2079
|
+
operation.value = type;
|
|
2080
|
+
let result;
|
|
2081
|
+
if (type === 'add') {
|
|
2082
|
+
result = await addVariant(variant.value.id, quantity, modifiers.value, promotion.value);
|
|
2083
|
+
}
|
|
2084
|
+
else {
|
|
2085
|
+
result = await removeVariant(variant.value.id, quantity, modifiers.value, promotion.value);
|
|
2086
|
+
useNotification('success', 'Товар удалён', `Товар${variant.value.name ? ` «${variant.value.name}»` : ''} удалён из корзины!`);
|
|
2087
|
+
}
|
|
2088
|
+
if (result) {
|
|
2089
|
+
useNotification('success', `Товар ${type === 'add' ? 'добавлен' : 'удалён'}`, `Товар${variant.value.name ? ` «${variant.value.name}»` : ''} ${type === 'add' ? 'добавлен в корзину' : 'удалён из корзины'}!`);
|
|
2090
|
+
}
|
|
2091
|
+
loading.value = false;
|
|
2092
|
+
};
|
|
2093
|
+
const add = async () => updateVariant('add', 1);
|
|
2094
|
+
const remove = async () => updateVariant('remove', totalQuantity.value);
|
|
2095
|
+
const getQuantity = (value) => {
|
|
2096
|
+
if (typeof value === 'string') {
|
|
2097
|
+
return parseInt(value, 10);
|
|
2098
|
+
}
|
|
2099
|
+
return value;
|
|
2100
|
+
};
|
|
2101
|
+
const increase = async (quantity = 1) => {
|
|
2102
|
+
quantityModel.value = getQuantity(quantityModel.value) + quantity;
|
|
2103
|
+
};
|
|
2104
|
+
const decrease = async (quantity = 1) => {
|
|
2105
|
+
quantityModel.value = Math.max(0, getQuantity(quantityModel.value) - quantity);
|
|
2106
|
+
};
|
|
2107
|
+
watch(totalQuantity, () => {
|
|
2108
|
+
quantityModel.value = totalQuantity.value;
|
|
2109
|
+
});
|
|
2110
|
+
watch(quantityModel, debounce(async (val) => {
|
|
2111
|
+
const difference = getQuantity(val) - totalQuantity.value;
|
|
2112
|
+
if (difference < 0) {
|
|
2113
|
+
await updateVariant('remove', Math.abs(difference));
|
|
2114
|
+
}
|
|
2115
|
+
else if (difference > 0) {
|
|
2116
|
+
await updateVariant('add', difference);
|
|
2117
|
+
}
|
|
2118
|
+
}, 1000));
|
|
2119
|
+
return {
|
|
2120
|
+
orderVariant,
|
|
2121
|
+
totalQuantity,
|
|
2122
|
+
quantityModel,
|
|
2123
|
+
add,
|
|
2124
|
+
increase,
|
|
2125
|
+
decrease,
|
|
2126
|
+
remove,
|
|
2127
|
+
loading,
|
|
2128
|
+
operation,
|
|
2129
|
+
};
|
|
2130
|
+
};
|
|
2131
|
+
|
|
2132
|
+
function getDeliveryMethod(order, settings) {
|
|
2133
|
+
if (!order.value || !settings.value) {
|
|
2134
|
+
return 'delivery';
|
|
2135
|
+
}
|
|
2136
|
+
const methods = settings.value.delivery_methods.map((method) => method.id);
|
|
2137
|
+
if (methods.indexOf(order.value.delivery_method.id) !== -1) {
|
|
2138
|
+
return order.value.delivery_method.id;
|
|
2139
|
+
}
|
|
2140
|
+
return methods[0];
|
|
2141
|
+
}
|
|
2142
|
+
function getStockId(order, stocks) {
|
|
2143
|
+
const availableStocks = stocks.value.map((stock) => stock.id);
|
|
2144
|
+
if (order.value && order.value.stock_id !== null && availableStocks.indexOf(order.value.stock_id) !== -1) {
|
|
2145
|
+
return order.value.stock_id;
|
|
2146
|
+
}
|
|
2147
|
+
return availableStocks[0];
|
|
2148
|
+
}
|
|
2149
|
+
function useCustomerAddresses(customer) {
|
|
2150
|
+
const addresses = ref([]);
|
|
2151
|
+
const loaded = ref(false);
|
|
2152
|
+
if (!customer.value || !customer.value.id) {
|
|
2153
|
+
loaded.value = true;
|
|
2154
|
+
}
|
|
2155
|
+
else {
|
|
2156
|
+
getCustomerAddresses({ count: 100 }).then((response) => {
|
|
2157
|
+
addresses.value = response.items;
|
|
2158
|
+
loaded.value = true;
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
return {
|
|
2162
|
+
addresses,
|
|
2163
|
+
loaded,
|
|
2164
|
+
};
|
|
2165
|
+
}
|
|
2166
|
+
function getDeliveryPayload(form, addressesResolver) {
|
|
2167
|
+
const data = { delivery_method: form.method };
|
|
2168
|
+
const errors = [];
|
|
2169
|
+
if (form.method === 'pickup') {
|
|
2170
|
+
if (form.pickup.stock_id) {
|
|
2171
|
+
data.stock_id = form.pickup.stock_id;
|
|
2172
|
+
}
|
|
2173
|
+
else {
|
|
2174
|
+
errors.push('Нужно выбрать точку самовывоза.');
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
else if (form.method === 'on_premise') {
|
|
2178
|
+
if (form.on_premise.stock_id) {
|
|
2179
|
+
data.stock_id = form.on_premise.stock_id;
|
|
2180
|
+
}
|
|
2181
|
+
else {
|
|
2182
|
+
errors.push('Нужно выбрать точку самовывоза.');
|
|
2183
|
+
}
|
|
2184
|
+
if (form.on_premise.table) {
|
|
2185
|
+
data.on_premise = { table: form.on_premise.table };
|
|
2186
|
+
}
|
|
2187
|
+
else {
|
|
2188
|
+
errors.push('Нужно указать номер стола.');
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
else if (form.method === 'delivery') {
|
|
2192
|
+
if (form.delivery.address.id) {
|
|
2193
|
+
data.delivery_address = { id: form.delivery.address.id };
|
|
2194
|
+
}
|
|
2195
|
+
else {
|
|
2196
|
+
const { errors: addressErrors, data: address } = useAddressFormValue(form.delivery.address, addressesResolver);
|
|
2197
|
+
if (addressErrors.length > 0) {
|
|
2198
|
+
errors.push(addressErrors[0]);
|
|
2199
|
+
}
|
|
2200
|
+
else {
|
|
2201
|
+
data.delivery_address = address;
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
if (form.deliver_at.mode === 'select' && form.deliver_at.date) {
|
|
2206
|
+
data.deliver_at = format(Date.parse(form.deliver_at.date), 'yyyy-MM-dd HH:mm');
|
|
2207
|
+
}
|
|
2208
|
+
return {
|
|
2209
|
+
data,
|
|
2210
|
+
errors,
|
|
2211
|
+
};
|
|
2212
|
+
}
|
|
2213
|
+
function useDeliveryCheckoutForm(emit) {
|
|
2214
|
+
var _a, _b, _c, _d;
|
|
2215
|
+
const { credentials, order, settings } = storeToRefs(useOrderStore());
|
|
2216
|
+
const { customer } = storeToRefs(useCustomerStore());
|
|
2217
|
+
const { stocks, addressesResolver } = storeToRefs(useStoreStore());
|
|
2218
|
+
const { addresses, loaded } = useCustomerAddresses(customer);
|
|
2219
|
+
const { totalPrice } = useTotalPrice();
|
|
2220
|
+
const ready = computed(() => loaded.value);
|
|
2221
|
+
const currentAddress = computed(() => { var _a; return (_a = order.value) === null || _a === void 0 ? void 0 : _a.delivery_address; });
|
|
2222
|
+
const saving = ref(false);
|
|
2223
|
+
const form = ref({
|
|
2224
|
+
method: getDeliveryMethod(order, settings),
|
|
2225
|
+
delivery: {
|
|
2226
|
+
address: getAddressForm(),
|
|
2227
|
+
},
|
|
2228
|
+
pickup: {
|
|
2229
|
+
stock_id: getStockId(order, stocks),
|
|
2230
|
+
},
|
|
2231
|
+
on_premise: {
|
|
2232
|
+
stock_id: getStockId(order, stocks),
|
|
2233
|
+
table: '',
|
|
2234
|
+
},
|
|
2235
|
+
deliver_at: {
|
|
2236
|
+
mode: 'asap',
|
|
2237
|
+
date: '',
|
|
2238
|
+
},
|
|
2239
|
+
});
|
|
2240
|
+
form.value.delivery.address.id = ((_b = (_a = order.value) === null || _a === void 0 ? void 0 : _a.delivery_address) === null || _b === void 0 ? void 0 : _b.id) || '';
|
|
2241
|
+
if ((_d = (_c = order.value) === null || _c === void 0 ? void 0 : _c.deliver_at_local) === null || _d === void 0 ? void 0 : _d.datetime) {
|
|
2242
|
+
form.value.deliver_at.mode = 'select';
|
|
2243
|
+
form.value.deliver_at.date = format(Date.parse(order.value.deliver_at_local.iso), 'yyyy-MM-dd HH:mm');
|
|
2244
|
+
}
|
|
2245
|
+
const priceIsNotEnough = computed(() => {
|
|
2246
|
+
var _a, _b;
|
|
2247
|
+
const method = (_a = settings.value) === null || _a === void 0 ? void 0 : _a.delivery_methods.find((item) => item.id === form.value.method);
|
|
2248
|
+
if (!method || !method.min_price || !method.min_price.value) {
|
|
2249
|
+
return false;
|
|
2250
|
+
}
|
|
2251
|
+
return method.min_price.value > (((_b = totalPrice.value) === null || _b === void 0 ? void 0 : _b.value) || 0);
|
|
2252
|
+
});
|
|
2253
|
+
const save = async () => {
|
|
2254
|
+
if (!credentials.value || !addressesResolver.value) {
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
else if (saving.value) {
|
|
2258
|
+
return;
|
|
2259
|
+
}
|
|
2260
|
+
const { data, errors } = getDeliveryPayload(form.value, addressesResolver.value);
|
|
2261
|
+
if (errors.length > 0) {
|
|
2262
|
+
useNotification('error', 'Ошибка', errors[0]);
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2265
|
+
saving.value = true;
|
|
2266
|
+
try {
|
|
2267
|
+
await setOrderCheckoutDelivery(credentials.value, data);
|
|
2268
|
+
emit('completed');
|
|
2269
|
+
}
|
|
2270
|
+
catch (e) {
|
|
2271
|
+
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось сохранить способ доставки.'));
|
|
2272
|
+
}
|
|
2273
|
+
finally {
|
|
2274
|
+
saving.value = false;
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
return {
|
|
2278
|
+
ready,
|
|
2279
|
+
form,
|
|
2280
|
+
addresses,
|
|
2281
|
+
currentAddress,
|
|
2282
|
+
addressesResolver,
|
|
2283
|
+
priceIsNotEnough,
|
|
2284
|
+
saving,
|
|
2285
|
+
save,
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
function getPaymentMethod(settings) {
|
|
2290
|
+
if (!settings.value) {
|
|
2291
|
+
return 'cash';
|
|
2292
|
+
}
|
|
2293
|
+
const available = settings.value.payment_methods.map((method) => method.id);
|
|
2294
|
+
return available[0];
|
|
2295
|
+
}
|
|
2296
|
+
function useBillSuggestions(unpaidAmount, staticAmounts = [10, 50, 200, 5000], availableBills = [100, 500, 1000]) {
|
|
2297
|
+
const { totalPrice } = useTotalPrice();
|
|
2298
|
+
const getClosestMultipleOf = (price, amount) => Math.ceil(price / amount) * amount;
|
|
2299
|
+
const suggestions = computed(() => {
|
|
2300
|
+
const items = new Set([
|
|
2301
|
+
...staticAmounts,
|
|
2302
|
+
...availableBills.map((billItem) => getClosestMultipleOf(unpaidAmount.value, billItem)),
|
|
2303
|
+
unpaidAmount.value,
|
|
2304
|
+
]);
|
|
2305
|
+
const bills = [...items]
|
|
2306
|
+
.filter((suggestion) => suggestion > unpaidAmount.value)
|
|
2307
|
+
.sort((first, second) => (first - second))
|
|
2308
|
+
.map((amount) => {
|
|
2309
|
+
var _a, _b;
|
|
2310
|
+
return ({
|
|
2311
|
+
value: amount,
|
|
2312
|
+
label: `${(_a = totalPrice.value) === null || _a === void 0 ? void 0 : _a.currency.prefix}${amount}${(_b = totalPrice.value) === null || _b === void 0 ? void 0 : _b.currency.suffix}`,
|
|
2313
|
+
});
|
|
2314
|
+
});
|
|
2315
|
+
bills.unshift({
|
|
2316
|
+
label: 'Без сдачи',
|
|
2317
|
+
value: '',
|
|
2318
|
+
});
|
|
2319
|
+
bills.push({
|
|
2320
|
+
label: 'Другая',
|
|
2321
|
+
value: 'custom',
|
|
2322
|
+
});
|
|
2323
|
+
return bills;
|
|
2324
|
+
});
|
|
2325
|
+
return {
|
|
2326
|
+
suggestions,
|
|
2327
|
+
};
|
|
2328
|
+
}
|
|
2329
|
+
function useBonusesPreviewChecker(order, credentials, bonuses, setBonuses) {
|
|
2330
|
+
var _a;
|
|
2331
|
+
const bonusesAreChecking = ref(false);
|
|
2332
|
+
const unpaidAmount = ref((_a = order.value) === null || _a === void 0 ? void 0 : _a.total_price);
|
|
2333
|
+
const bonusesChecker = async () => {
|
|
2334
|
+
var _a;
|
|
2335
|
+
if (!credentials.value) {
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2338
|
+
else if (bonusesAreChecking.value) {
|
|
2339
|
+
return;
|
|
2340
|
+
}
|
|
2341
|
+
else if (!bonuses.value) {
|
|
2342
|
+
unpaidAmount.value = (_a = order.value) === null || _a === void 0 ? void 0 : _a.total_price;
|
|
2343
|
+
return;
|
|
2344
|
+
}
|
|
2345
|
+
bonusesAreChecking.value = true;
|
|
2346
|
+
try {
|
|
2347
|
+
const preview = await getOrderBonusesPaymentPreview(credentials.value, bonuses.value);
|
|
2348
|
+
unpaidAmount.value = preview.unpaid;
|
|
2349
|
+
if (parseFloat(bonuses.value) > parseFloat(preview.bonuses.trimmed)) {
|
|
2350
|
+
setBonuses(preview.bonuses.trimmed);
|
|
2351
|
+
useNotification('warning', 'Сумма бонусов изменена', 'Вы указали сумму бонусов, превышающую лимит списания. Мы изменили сумму на максимально доступную.');
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
catch (e) {
|
|
2355
|
+
//
|
|
2356
|
+
}
|
|
2357
|
+
finally {
|
|
2358
|
+
bonusesAreChecking.value = false;
|
|
2359
|
+
}
|
|
2360
|
+
};
|
|
2361
|
+
watch(bonuses, debounce(async () => bonusesChecker(), 1000));
|
|
2362
|
+
return {
|
|
2363
|
+
unpaidAmount,
|
|
2364
|
+
bonusesAreChecking,
|
|
2365
|
+
};
|
|
2366
|
+
}
|
|
2367
|
+
function getPaymentsPayload(form) {
|
|
2368
|
+
const payments = [];
|
|
2369
|
+
if (parseFloat(form.bonuses) > 0.0) {
|
|
2370
|
+
payments.push({
|
|
2371
|
+
method: 'bonuses',
|
|
2372
|
+
amount: form.bonuses,
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2375
|
+
const payment = { method: form.method };
|
|
2376
|
+
if (form.method === 'cash' && form.bill) {
|
|
2377
|
+
payment.bill = form.bill;
|
|
2378
|
+
}
|
|
2379
|
+
else if (form.method === 'card_token') {
|
|
2380
|
+
payment.card_token_id = form.card_token_id;
|
|
2381
|
+
}
|
|
2382
|
+
else if (form.method === 'cloudpayments') {
|
|
2383
|
+
payment.save_card = form.save_card === true;
|
|
2384
|
+
}
|
|
2385
|
+
payments.push(payment);
|
|
2386
|
+
return payments;
|
|
2387
|
+
}
|
|
2388
|
+
function useDeliveryPaymentsForm(emit) {
|
|
2389
|
+
const { order, credentials, settings } = storeToRefs(useOrderStore());
|
|
2390
|
+
const form = ref({
|
|
2391
|
+
method: getPaymentMethod(settings),
|
|
2392
|
+
bill: '',
|
|
2393
|
+
save_card: false,
|
|
2394
|
+
bonuses: '',
|
|
2395
|
+
card_token_id: '',
|
|
2396
|
+
});
|
|
2397
|
+
const saving = ref(false);
|
|
2398
|
+
const bonuses = computed(() => form.value.bonuses);
|
|
2399
|
+
const { unpaidAmount, bonusesAreChecking } = useBonusesPreviewChecker(order, credentials, bonuses, (amount) => {
|
|
2400
|
+
form.value.bonuses = amount;
|
|
2401
|
+
});
|
|
2402
|
+
const save = async () => {
|
|
2403
|
+
if (!credentials.value) {
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
else if (saving.value) {
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
2409
|
+
const payments = getPaymentsPayload(form.value);
|
|
2410
|
+
try {
|
|
2411
|
+
await setOrderCheckoutPayment(credentials.value, { payments });
|
|
2412
|
+
emit('completed');
|
|
2413
|
+
}
|
|
2414
|
+
catch (e) {
|
|
2415
|
+
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось сохранить способ оплаты.'));
|
|
2416
|
+
}
|
|
2417
|
+
finally {
|
|
2418
|
+
saving.value = false;
|
|
2419
|
+
}
|
|
2420
|
+
};
|
|
2421
|
+
return {
|
|
2422
|
+
form,
|
|
2423
|
+
unpaidAmount,
|
|
2424
|
+
bonusesAreChecking,
|
|
2425
|
+
saving,
|
|
2426
|
+
save,
|
|
2427
|
+
};
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
function useCheckoutSummary(emit) {
|
|
2431
|
+
const orderStore = useOrderStore();
|
|
2432
|
+
const { credentials, settings } = storeToRefs(orderStore);
|
|
2433
|
+
const { store, city } = storeToRefs(useStoreStore());
|
|
2434
|
+
const form = ref({
|
|
2435
|
+
persons_count: '',
|
|
2436
|
+
notes: '',
|
|
2437
|
+
});
|
|
2438
|
+
const hasPersonsCount = computed(() => {
|
|
2439
|
+
if (!settings.value) {
|
|
2440
|
+
return false;
|
|
2441
|
+
}
|
|
2442
|
+
const index = settings.value.options.findIndex((option) => option.kind === 'persons_count');
|
|
2443
|
+
return index !== -1;
|
|
2444
|
+
});
|
|
2445
|
+
const saving = ref(false);
|
|
2446
|
+
const save = async () => {
|
|
2447
|
+
if (!credentials.value) {
|
|
2448
|
+
return;
|
|
2449
|
+
}
|
|
2450
|
+
else if (saving.value) {
|
|
2451
|
+
return;
|
|
2452
|
+
}
|
|
2453
|
+
const payload = {
|
|
2454
|
+
notes: form.value.notes,
|
|
2455
|
+
};
|
|
2456
|
+
if (hasPersonsCount.value && form.value.persons_count) {
|
|
2457
|
+
payload.notes = `Персон: ${form.value.persons_count}\n\n${payload.notes}`.trim();
|
|
2458
|
+
}
|
|
2459
|
+
saving.value = true;
|
|
2460
|
+
try {
|
|
2461
|
+
const response = await checkoutOrder(credentials.value, payload);
|
|
2462
|
+
if (response.confirmation_required) {
|
|
2463
|
+
emit('confirmation', credentials.value);
|
|
2464
|
+
}
|
|
2465
|
+
else {
|
|
2466
|
+
emit('completed', response);
|
|
2467
|
+
}
|
|
2468
|
+
if (store.value && city.value) {
|
|
2469
|
+
await orderStore.recreate(store.value.id, city.value.id);
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
catch (e) {
|
|
2473
|
+
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось оформить заказ.'));
|
|
2474
|
+
}
|
|
2475
|
+
finally {
|
|
2476
|
+
saving.value = false;
|
|
2477
|
+
}
|
|
2478
|
+
};
|
|
2479
|
+
return {
|
|
2480
|
+
form,
|
|
2481
|
+
hasPersonsCount,
|
|
2482
|
+
saving,
|
|
2483
|
+
save,
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
function useCheckoutTotal() {
|
|
2488
|
+
const { credentials } = storeToRefs(useOrderStore());
|
|
2489
|
+
const loading = ref(false);
|
|
2490
|
+
const total = ref(null);
|
|
2491
|
+
const load = async () => {
|
|
2492
|
+
if (loading.value) {
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
else if (!credentials.value) {
|
|
2496
|
+
return;
|
|
2497
|
+
}
|
|
2498
|
+
loading.value = true;
|
|
2499
|
+
try {
|
|
2500
|
+
total.value = await getOrderCheckoutTotal(credentials.value);
|
|
2501
|
+
}
|
|
2502
|
+
catch (e) {
|
|
2503
|
+
//
|
|
2504
|
+
}
|
|
2505
|
+
finally {
|
|
2506
|
+
loading.value = false;
|
|
2507
|
+
}
|
|
2508
|
+
};
|
|
2509
|
+
return {
|
|
2510
|
+
loading,
|
|
2511
|
+
load,
|
|
2512
|
+
total,
|
|
2513
|
+
};
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
function useSingleModifier(props, emit) {
|
|
2517
|
+
const value = computed({
|
|
2518
|
+
get: () => props.modelValue,
|
|
2519
|
+
set: (val) => emit('update:modelValue', val),
|
|
2520
|
+
});
|
|
2521
|
+
const checked = computed({
|
|
2522
|
+
get: () => value.value.quantity > 0,
|
|
2523
|
+
set: (val) => {
|
|
2524
|
+
value.value.quantity = val ? 1 : 0;
|
|
2525
|
+
},
|
|
2526
|
+
});
|
|
2527
|
+
const shouldUseQuantityControls = computed(() => props.modifier.max_quantity > 1);
|
|
2528
|
+
const increase = () => {
|
|
2529
|
+
if (props.limitReached) {
|
|
2530
|
+
return;
|
|
2531
|
+
}
|
|
2532
|
+
value.value.quantity = Math.min(value.value.quantity + 1, props.modifier.max_quantity);
|
|
2533
|
+
};
|
|
2534
|
+
const decrease = () => {
|
|
2535
|
+
value.value.quantity = Math.max(value.value.quantity - 1, props.modifier.min_quantity);
|
|
2536
|
+
};
|
|
2537
|
+
return {
|
|
2538
|
+
value,
|
|
2539
|
+
checked,
|
|
2540
|
+
shouldUseQuantityControls,
|
|
2541
|
+
increase,
|
|
2542
|
+
decrease,
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
function getModifierQuantity(modifier, value) {
|
|
2547
|
+
const index = value.value.findIndex((item) => item.modifier_id === modifier.modifier.id);
|
|
2548
|
+
if (index === -1) {
|
|
2549
|
+
return 0;
|
|
2550
|
+
}
|
|
2551
|
+
return value.value[index].quantity;
|
|
2552
|
+
}
|
|
2553
|
+
function getDefaultModifiersGroupModifiers(group, value) {
|
|
2554
|
+
const modifiers = {};
|
|
2555
|
+
group.modifiers.forEach((modifier) => {
|
|
2556
|
+
const quantity = Array.isArray(value.value) ? getModifierQuantity(modifier, value) : 0;
|
|
2557
|
+
modifiers[modifier.modifier.id] = {
|
|
2558
|
+
quantity,
|
|
2559
|
+
modifier_id: modifier.modifier.id,
|
|
2560
|
+
};
|
|
2561
|
+
});
|
|
2562
|
+
return modifiers;
|
|
2563
|
+
}
|
|
2564
|
+
function getSelectedModifiers$1(group, modifiers) {
|
|
2565
|
+
const selected = [];
|
|
2566
|
+
Object.keys(modifiers).forEach((modifierId) => {
|
|
2567
|
+
if (!modifiers[modifierId].quantity) {
|
|
2568
|
+
return;
|
|
2569
|
+
}
|
|
2570
|
+
selected.push({
|
|
2571
|
+
modifiers_group_id: group.group.id,
|
|
2572
|
+
modifier_id: modifierId,
|
|
2573
|
+
quantity: modifiers[modifierId].quantity,
|
|
2574
|
+
});
|
|
2575
|
+
});
|
|
2576
|
+
return selected;
|
|
2577
|
+
}
|
|
2578
|
+
function useModifiersGroup(props, emit) {
|
|
2579
|
+
const value = computed({
|
|
2580
|
+
get: () => props.modelValue,
|
|
2581
|
+
set: (val) => emit('update:modelValue', val),
|
|
2582
|
+
});
|
|
2583
|
+
const selectedModifier = ref('');
|
|
2584
|
+
const modifiers = ref(getDefaultModifiersGroupModifiers(props.group, value));
|
|
2585
|
+
const shouldUseQuantityControls = computed(() => props.group.max_quantity > 1);
|
|
2586
|
+
const totalSelectedCount = computed(() => {
|
|
2587
|
+
return value.value
|
|
2588
|
+
.map((modifier) => modifier.quantity)
|
|
2589
|
+
.reduce((current, total) => current + total, 0);
|
|
2590
|
+
});
|
|
2591
|
+
const limitReached = computed(() => {
|
|
2592
|
+
if (!shouldUseQuantityControls.value) {
|
|
2593
|
+
return selectedModifier.value !== '';
|
|
2594
|
+
}
|
|
2595
|
+
return totalSelectedCount.value >= props.group.max_quantity;
|
|
2596
|
+
});
|
|
2597
|
+
const requiredModifierIsMissing = computed(() => {
|
|
2598
|
+
if (!props.group.is_required) {
|
|
2599
|
+
return false;
|
|
2600
|
+
}
|
|
2601
|
+
else if (props.group.min_quantity === 0) {
|
|
2602
|
+
return false;
|
|
2603
|
+
}
|
|
2604
|
+
return totalSelectedCount.value < props.group.min_quantity;
|
|
2605
|
+
});
|
|
2606
|
+
watch(selectedModifier, (val) => {
|
|
2607
|
+
if (!val) {
|
|
2608
|
+
value.value = [];
|
|
2609
|
+
return;
|
|
2610
|
+
}
|
|
2611
|
+
value.value = [{
|
|
2612
|
+
modifiers_group_id: props.group.group.id,
|
|
2613
|
+
modifier_id: val,
|
|
2614
|
+
quantity: 1,
|
|
2615
|
+
}];
|
|
2616
|
+
});
|
|
2617
|
+
watch(modifiers, (val) => {
|
|
2618
|
+
value.value = getSelectedModifiers$1(props.group, val);
|
|
2619
|
+
}, { deep: true });
|
|
2620
|
+
return {
|
|
2621
|
+
selectedModifier,
|
|
2622
|
+
modifiers,
|
|
2623
|
+
shouldUseQuantityControls,
|
|
2624
|
+
requiredModifierIsMissing,
|
|
2625
|
+
limitReached,
|
|
2626
|
+
};
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
function getModifiers(product, variant) {
|
|
2630
|
+
const modifiers = {};
|
|
2631
|
+
((product === null || product === void 0 ? void 0 : product.modifiers) || []).forEach((modifier) => {
|
|
2632
|
+
modifiers[modifier.modifier.id] = {
|
|
2633
|
+
modifier_id: modifier.modifier.id,
|
|
2634
|
+
quantity: 0,
|
|
2635
|
+
};
|
|
2636
|
+
});
|
|
2637
|
+
((product === null || product === void 0 ? void 0 : product.modifiers_groups) || []).forEach((group) => {
|
|
2638
|
+
modifiers[group.group.id] = [];
|
|
2639
|
+
});
|
|
2640
|
+
if (!variant.value || !variant.value.selected_modifiers || !variant.value.selected_modifiers.modifiers) {
|
|
2641
|
+
return modifiers;
|
|
2642
|
+
}
|
|
2643
|
+
else if (!variant.value.selected_modifiers.modifiers.length) {
|
|
2644
|
+
return modifiers;
|
|
2645
|
+
}
|
|
2646
|
+
variant.value.selected_modifiers.modifiers.forEach((modifier) => {
|
|
2647
|
+
if (typeof modifier.modifiers_group_id !== 'undefined' && modifier.modifiers_group_id) {
|
|
2648
|
+
modifiers[modifier.modifiers_group_id].push(modifier);
|
|
2649
|
+
}
|
|
2650
|
+
else if (typeof modifier.modifier_id !== 'undefined' && modifier.modifier_id) {
|
|
2651
|
+
modifiers[modifier.modifier_id] = {
|
|
2652
|
+
modifier_id: modifier.modifier_id,
|
|
2653
|
+
quantity: modifier.quantity,
|
|
2654
|
+
};
|
|
2655
|
+
}
|
|
2656
|
+
});
|
|
2657
|
+
return modifiers;
|
|
2658
|
+
}
|
|
2659
|
+
function getSelectedModifiers(modifiers) {
|
|
2660
|
+
const selected = [];
|
|
2661
|
+
Object.keys(modifiers.value).forEach((modifierId) => {
|
|
2662
|
+
const isGroup = Array.isArray(modifiers.value[modifierId]);
|
|
2663
|
+
if (!isGroup && !modifiers.value[modifierId].quantity) {
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
else if (!isGroup) {
|
|
2667
|
+
selected.push({
|
|
2668
|
+
modifier_id: modifierId,
|
|
2669
|
+
quantity: modifiers.value[modifierId].quantity,
|
|
2670
|
+
});
|
|
2671
|
+
return;
|
|
2672
|
+
}
|
|
2673
|
+
modifiers.value[modifierId].forEach((modifier) => {
|
|
2674
|
+
if (!modifier.modifier_id || !modifier.quantity || !modifier.modifiers_group_id) {
|
|
2675
|
+
return;
|
|
2676
|
+
}
|
|
2677
|
+
selected.push({
|
|
2678
|
+
modifiers_group_id: modifier.modifiers_group_id,
|
|
2679
|
+
modifier_id: modifier.modifier_id,
|
|
2680
|
+
quantity: modifier.quantity,
|
|
2681
|
+
});
|
|
2682
|
+
});
|
|
2683
|
+
});
|
|
2684
|
+
return selected;
|
|
2685
|
+
}
|
|
2686
|
+
function useModifiers(product, variant, recalculate) {
|
|
2687
|
+
var _a, _b;
|
|
2688
|
+
const modifiersHash = ref(((_b = (_a = variant.value) === null || _a === void 0 ? void 0 : _a.selected_modifiers) === null || _b === void 0 ? void 0 : _b.hash) || null);
|
|
2689
|
+
const modifiers = ref(getModifiers(product, variant));
|
|
2690
|
+
const selectedModifiers = computed(() => getSelectedModifiers(modifiers));
|
|
2691
|
+
watch(variant, () => {
|
|
2692
|
+
modifiers.value = getModifiers(product, variant);
|
|
2693
|
+
});
|
|
2694
|
+
watch(selectedModifiers, async () => {
|
|
2695
|
+
modifiersHash.value = await recalculate(selectedModifiers);
|
|
2696
|
+
});
|
|
2697
|
+
return {
|
|
2698
|
+
modifiers,
|
|
2699
|
+
selectedModifiers,
|
|
2700
|
+
modifiersHash,
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2704
|
+
async function recalculatePrice(variant, modifiers) {
|
|
2705
|
+
if (!variant.value) {
|
|
2706
|
+
return null;
|
|
2707
|
+
}
|
|
2708
|
+
else if (!modifiers.value.length) {
|
|
2709
|
+
return null;
|
|
2710
|
+
}
|
|
2711
|
+
const { cityId } = storeToRefs(useStoreStore());
|
|
2712
|
+
try {
|
|
2713
|
+
return await getProductVariantPrice(variant.value.product_id, variant.value.id, modifiers.value, {
|
|
2714
|
+
city_id: cityId.value || undefined,
|
|
2715
|
+
});
|
|
2716
|
+
}
|
|
2717
|
+
catch (e) {
|
|
2718
|
+
//
|
|
2719
|
+
}
|
|
2720
|
+
return null;
|
|
2721
|
+
}
|
|
2722
|
+
function getProductVariantsPricesRange(variants) {
|
|
2723
|
+
if (!variants.length) {
|
|
2724
|
+
return null;
|
|
2725
|
+
}
|
|
2726
|
+
const sorted = [...variants].sort((first, second) => Math.sign(first.price.value - second.price.value));
|
|
2727
|
+
return {
|
|
2728
|
+
min: sorted[0].price,
|
|
2729
|
+
max: sorted[sorted.length - 1].price,
|
|
2730
|
+
};
|
|
2731
|
+
}
|
|
2732
|
+
function useVariantPrice(variants, variant) {
|
|
2733
|
+
const result = ref(null);
|
|
2734
|
+
const recalculating = ref(false);
|
|
2735
|
+
const totalPrice = computed(() => {
|
|
2736
|
+
if (result.value !== null) {
|
|
2737
|
+
return {
|
|
2738
|
+
recalculated: true,
|
|
2739
|
+
recalculating: recalculating.value,
|
|
2740
|
+
price: result.value.price,
|
|
2741
|
+
original_price: result.value.original_price,
|
|
2742
|
+
has_discount: result.value.has_discount,
|
|
2743
|
+
discount_id: result.value.discount_id,
|
|
2744
|
+
discount_difference: result.value.discount_difference,
|
|
2745
|
+
discount_percentage: result.value.discount_percentage,
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2748
|
+
else if (!variant.value) {
|
|
2749
|
+
return null;
|
|
2750
|
+
}
|
|
2751
|
+
return {
|
|
2752
|
+
recalculated: false,
|
|
2753
|
+
recalculating: recalculating.value,
|
|
2754
|
+
price: variant.value.price,
|
|
2755
|
+
original_price: variant.value.original_price,
|
|
2756
|
+
has_discount: variant.value.has_discount,
|
|
2757
|
+
discount_id: variant.value.discount_id,
|
|
2758
|
+
discount_difference: variant.value.discount_difference,
|
|
2759
|
+
discount_percentage: variant.value.discount_percentage,
|
|
2760
|
+
};
|
|
2761
|
+
});
|
|
2762
|
+
const pricesRange = computed(() => getProductVariantsPricesRange(variants));
|
|
2763
|
+
const recalculate = async (modifiers) => {
|
|
2764
|
+
if (recalculating.value) {
|
|
2765
|
+
return null;
|
|
2766
|
+
}
|
|
2767
|
+
recalculating.value = true;
|
|
2768
|
+
result.value = await recalculatePrice(variant, modifiers);
|
|
2769
|
+
recalculating.value = false;
|
|
2770
|
+
return result.value !== null ? result.value.modifiers_hash : null;
|
|
2771
|
+
};
|
|
2772
|
+
return {
|
|
2773
|
+
totalPrice,
|
|
2774
|
+
pricesRange,
|
|
2775
|
+
recalculating,
|
|
2776
|
+
recalculate,
|
|
2777
|
+
};
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
function getOptionsList(variants) {
|
|
2781
|
+
const options = [];
|
|
2782
|
+
if (variants.length <= 1) {
|
|
2783
|
+
return options;
|
|
2784
|
+
}
|
|
2785
|
+
variants.forEach((variant) => {
|
|
2786
|
+
if (!variant.option_values || !variant.option_values.length) {
|
|
2787
|
+
return;
|
|
2788
|
+
}
|
|
2789
|
+
variant.option_values.forEach((optionValue) => {
|
|
2790
|
+
if (!optionValue.option || !optionValue.option.id) {
|
|
2791
|
+
return;
|
|
2792
|
+
}
|
|
2793
|
+
const optionIndex = options.findIndex((option) => { var _a; return option.id === ((_a = optionValue.option) === null || _a === void 0 ? void 0 : _a.id); });
|
|
2794
|
+
if (optionIndex === -1) {
|
|
2795
|
+
options.push({
|
|
2796
|
+
id: optionValue.option.id,
|
|
2797
|
+
name: optionValue.option.name,
|
|
2798
|
+
type: optionValue.option.type,
|
|
2799
|
+
values: [optionValue],
|
|
2800
|
+
});
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
const valueIndex = options[optionIndex].values.findIndex((item) => item.id === optionValue.id);
|
|
2804
|
+
if (valueIndex !== -1) {
|
|
2805
|
+
return;
|
|
2806
|
+
}
|
|
2807
|
+
options[optionIndex].values.push(optionValue);
|
|
2808
|
+
});
|
|
2809
|
+
});
|
|
2810
|
+
return options;
|
|
2811
|
+
}
|
|
2812
|
+
function useVariant(variants) {
|
|
2813
|
+
const options = ref(getOptionsList(variants));
|
|
2814
|
+
const selectedOptions = ref({});
|
|
2815
|
+
options.value.forEach((option) => {
|
|
2816
|
+
selectedOptions.value[option.id] = option.values.length > 0 ? option.values[0].id : null;
|
|
2817
|
+
});
|
|
2818
|
+
const variant = computed(() => {
|
|
2819
|
+
if (!Array.isArray(variants) || !variants.length) {
|
|
2820
|
+
return null;
|
|
2821
|
+
}
|
|
2822
|
+
else if (variants.length === 1) {
|
|
2823
|
+
return variants[0];
|
|
2824
|
+
}
|
|
2825
|
+
else if (!Object.keys(selectedOptions.value).length) {
|
|
2826
|
+
return variants[0];
|
|
2827
|
+
}
|
|
2828
|
+
const variantIndex = variants.findIndex((item) => {
|
|
2829
|
+
if (!item.option_values || !item.option_values.length) {
|
|
2830
|
+
return false;
|
|
2831
|
+
}
|
|
2832
|
+
return item.option_values.every((optionValue) => {
|
|
2833
|
+
if (!optionValue.option || !optionValue.option.id) {
|
|
2834
|
+
return false;
|
|
2835
|
+
}
|
|
2836
|
+
else if (typeof selectedOptions.value[optionValue.option.id] === 'undefined') {
|
|
2837
|
+
return false;
|
|
2838
|
+
}
|
|
2839
|
+
else if (selectedOptions.value[optionValue.option.id] !== optionValue.id) {
|
|
2840
|
+
return false;
|
|
2841
|
+
}
|
|
2842
|
+
return true;
|
|
2843
|
+
});
|
|
2844
|
+
});
|
|
2845
|
+
if (variantIndex === -1) {
|
|
2846
|
+
return null;
|
|
2847
|
+
}
|
|
2848
|
+
return variants[variantIndex];
|
|
2849
|
+
});
|
|
2850
|
+
return {
|
|
2851
|
+
variant,
|
|
2852
|
+
options,
|
|
2853
|
+
selectedOptions,
|
|
2854
|
+
};
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
function useProductItem(errorHandler) {
|
|
2858
|
+
return useItemLoader(getProduct, getApiErrorHandler(errorHandler, function (e) {
|
|
2859
|
+
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Товар не найден.'));
|
|
2860
|
+
}));
|
|
2861
|
+
}
|
|
2862
|
+
function useProductCard(item) {
|
|
2863
|
+
var _a;
|
|
2864
|
+
const product = ref({
|
|
2865
|
+
id: item.id,
|
|
2866
|
+
short_id: item.short_id,
|
|
2867
|
+
category_id: Array.isArray(item.categories) && item.categories.length > 0 ? item.categories[0].id : null,
|
|
2868
|
+
slug: item.slug,
|
|
2869
|
+
name: item.name,
|
|
2870
|
+
description: item.description,
|
|
2871
|
+
images: item.media || [],
|
|
2872
|
+
modifiers: item.modifiers || [],
|
|
2873
|
+
modifiers_groups: item.modifiers_groups || [],
|
|
2874
|
+
variants_count: ((_a = item.variants) === null || _a === void 0 ? void 0 : _a.length) || 0,
|
|
2875
|
+
has_images: (item.media || []).length > 0,
|
|
2876
|
+
has_modifiers: (item.modifiers || []).length > 0 || (item.modifiers_groups || []).length > 0,
|
|
2877
|
+
});
|
|
2878
|
+
const { variant, options, selectedOptions, } = useVariant(item.variants || []);
|
|
2879
|
+
const { totalPrice, pricesRange, recalculate, } = useVariantPrice(item.variants || [], variant);
|
|
2880
|
+
const { modifiers, selectedModifiers, modifiersHash, } = useModifiers(item, variant, recalculate);
|
|
2881
|
+
return {
|
|
2882
|
+
product,
|
|
2883
|
+
variant,
|
|
2884
|
+
options,
|
|
2885
|
+
selectedOptions,
|
|
2886
|
+
pricesRange,
|
|
2887
|
+
totalPrice,
|
|
2888
|
+
modifiers,
|
|
2889
|
+
modifiersHash,
|
|
2890
|
+
selectedModifiers,
|
|
2891
|
+
};
|
|
2892
|
+
}
|
|
2893
|
+
|
|
1551
2894
|
function useProductsPricesRange(categoryId, errorHandler) {
|
|
1552
2895
|
return useDataLoader(async () => getProductsPricesRange(categoryId), getApiErrorHandler(errorHandler, function (e) {
|
|
1553
2896
|
useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить диапазон цен.'));
|
|
@@ -2131,4 +3474,4 @@ function subscribeToOrderEvents(order) {
|
|
|
2131
3474
|
});
|
|
2132
3475
|
}
|
|
2133
3476
|
|
|
2134
|
-
export { AuthenticationEvent, AuthenticationResultType, AuthenticationStage, ZenkyInjection, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getWebsocketsConnection, initializePromotions, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useOfferItem, useOffersList, useOrderItem, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, usePromotionsStore, useRegistration, useReversedTree, useRewardsSelector, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity };
|
|
3477
|
+
export { AuthenticationEvent, AuthenticationResultType, AuthenticationStage, CheckoutStage, ProductsFiltersType, ProductsSorting, ProductsSourceType, ZenkyInjection, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductVariantsPricesRange, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getUpdatedVariants, getWebsocketsConnection, initializeOrderCustomer, initializePromotions, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useBillSuggestions, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCheckoutConfirmation, useCheckoutSummary, useCheckoutTotal, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerCheckoutForm, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useDeliveryCheckoutForm, useDeliveryPaymentsForm, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useModifiers, useModifiersGroup, useOfferItem, useOffersList, useOrderCheckout, useOrderItem, useOrderStore, useOrderVariants, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductCard, useProductItem, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, usePromotionsStore, useRegistration, useReversedTree, useRewardsSelector, useSingleModifier, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity, useTotalPrice, useTotalQuantity, useVariant, useVariantControls, useVariantPrice };
|