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