@isoftdata/svelte-ecommerce 1.0.0-beta.4 → 1.0.0-beta.6
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/README.md +56 -56
- package/dist/EcommerceCategoryMapConfiguration.svelte +251 -251
- package/dist/EcommerceConditionMapConfiguration.svelte +192 -192
- package/dist/EcommerceConfiguration.svelte +204 -199
- package/dist/EcommerceDefaults.svelte +388 -352
- package/dist/EcommerceListingDetails.svelte +854 -852
- package/dist/EcommercePartTypeConfig.svelte +283 -277
- package/dist/EcommerceStoreConfiguration.svelte +251 -251
- package/dist/PolicyList.svelte +53 -54
- package/dist/helpers/listing.d.ts +19 -1
- package/dist/helpers/listing.js +112 -16
- package/dist/utils.d.ts +2 -1
- package/package.json +14 -13
|
@@ -1,251 +1,251 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { i18n } from 'i18next'
|
|
3
|
-
|
|
4
|
-
import { getContext } from 'svelte'
|
|
5
|
-
import Table from '@isoftdata/svelte-table'
|
|
6
|
-
import { klona } from 'klona'
|
|
7
|
-
import Modal from '@isoftdata/svelte-modal'
|
|
8
|
-
import Checkbox from '@isoftdata/svelte-checkbox'
|
|
9
|
-
import Button from '@isoftdata/svelte-button'
|
|
10
|
-
import Select from '@isoftdata/svelte-select'
|
|
11
|
-
import { translate as defaultTranslate, booleanToYesNo as yesNo } from '@isoftdata/utility-string'
|
|
12
|
-
import type {
|
|
13
|
-
EbayLocation,
|
|
14
|
-
EbayPolicy,
|
|
15
|
-
EcommerceCondition,
|
|
16
|
-
EcommercePartnerConfiguration,
|
|
17
|
-
EcommerceStoreConfig,
|
|
18
|
-
Store,
|
|
19
|
-
} from './utils.js'
|
|
20
|
-
import EcommerceDefaults from './EcommerceDefaults.svelte'
|
|
21
|
-
|
|
22
|
-
const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
|
|
23
|
-
|
|
24
|
-
interface Props {
|
|
25
|
-
ebayLocationList?: Array<EbayLocation>
|
|
26
|
-
ebayPolicyList?: Array<EbayPolicy>
|
|
27
|
-
ecommerceConditionList: Array<EcommerceCondition>
|
|
28
|
-
partnerConfigurationList?: Array<EcommercePartnerConfiguration>
|
|
29
|
-
selectedEcommercePartnerId: number
|
|
30
|
-
storeList: Array<Store>
|
|
31
|
-
partnerConfigurationChanged: (partnerConfig: EcommercePartnerConfiguration) => Promise<void>
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let {
|
|
35
|
-
ebayLocationList = [],
|
|
36
|
-
ebayPolicyList = [],
|
|
37
|
-
ecommerceConditionList = [],
|
|
38
|
-
partnerConfigurationList = [],
|
|
39
|
-
selectedEcommercePartnerId,
|
|
40
|
-
storeList = [],
|
|
41
|
-
partnerConfigurationChanged,
|
|
42
|
-
}: Props = $props()
|
|
43
|
-
|
|
44
|
-
let newStoreConfig: EcommerceStoreConfig = Object.freeze({
|
|
45
|
-
active: true,
|
|
46
|
-
defaults: {
|
|
47
|
-
brandMapping: undefined,
|
|
48
|
-
conditionDescription: undefined,
|
|
49
|
-
conditionId: undefined,
|
|
50
|
-
fulfillmentPolicies: undefined,
|
|
51
|
-
fulfillmentTimeUnit: undefined,
|
|
52
|
-
fulfillmentTimeValue: undefined,
|
|
53
|
-
listingDescriptionTemplate: undefined,
|
|
54
|
-
listingDuration: undefined,
|
|
55
|
-
listingFormat: undefined,
|
|
56
|
-
listingTitleTemplate: undefined,
|
|
57
|
-
manufacturerPartNumberMapping: undefined,
|
|
58
|
-
oemNumberMapping: undefined,
|
|
59
|
-
packageType: undefined,
|
|
60
|
-
paymentPolicies: undefined,
|
|
61
|
-
pricingModifier: undefined,
|
|
62
|
-
returnPolicies: undefined,
|
|
63
|
-
shippingLengthUnit: undefined,
|
|
64
|
-
shippingWeightUnit: undefined,
|
|
65
|
-
storePickupAllowed: undefined,
|
|
66
|
-
},
|
|
67
|
-
merchantLocationKey: undefined,
|
|
68
|
-
name: '',
|
|
69
|
-
storeId: 0,
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
let show = $state(false)
|
|
73
|
-
let selectedStoreConfigRow = $state<EcommerceStoreConfig | null>(null)
|
|
74
|
-
|
|
75
|
-
// If we had more than one ecommercepartner, this would change depending on selected partner id
|
|
76
|
-
let selectedPartnerConfig = $derived(
|
|
77
|
-
partnerConfigurationList.find(row => row.ecommercePartnerId === selectedEcommercePartnerId),
|
|
78
|
-
)
|
|
79
|
-
// Get the store rows from the partnerconfig row
|
|
80
|
-
let selectedPartnerConfigStoreRows = $derived(selectedPartnerConfig?.defaults?.store || [])
|
|
81
|
-
|
|
82
|
-
// Filter available ebay locations depending on whether we're adding or editing
|
|
83
|
-
let availableLocations = $derived.by(() => {
|
|
84
|
-
const configuredEbayLocations = selectedPartnerConfigStoreRows.map(row => row.merchantLocationKey)
|
|
85
|
-
const isEditingExisting =
|
|
86
|
-
selectedStoreConfigRow?.name !== null &&
|
|
87
|
-
configuredEbayLocations.includes(selectedStoreConfigRow?.merchantLocationKey)
|
|
88
|
-
|
|
89
|
-
if (isEditingExisting) {
|
|
90
|
-
return ebayLocationList
|
|
91
|
-
}
|
|
92
|
-
return ebayLocationList.filter(location => !configuredEbayLocations.includes(location.ebayName))
|
|
93
|
-
})
|
|
94
|
-
// Filter available stores based on whether we're adding or editing existing
|
|
95
|
-
let availableStores = $derived.by(() => {
|
|
96
|
-
if (!selectedStoreConfigRow) return storeList
|
|
97
|
-
|
|
98
|
-
// Get the IDs of already configured stores
|
|
99
|
-
const configuredStoreIds = selectedPartnerConfigStoreRows.map(row => row.storeId)
|
|
100
|
-
const isEditingExisting =
|
|
101
|
-
selectedStoreConfigRow.storeId !== null && configuredStoreIds.includes(selectedStoreConfigRow.storeId)
|
|
102
|
-
|
|
103
|
-
if (isEditingExisting) {
|
|
104
|
-
return storeList
|
|
105
|
-
}
|
|
106
|
-
// If adding new, filter out already configured stores
|
|
107
|
-
return storeList.filter(store => !configuredStoreIds.includes(store.storeId))
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
async function confirm() {
|
|
111
|
-
if (!selectedStoreConfigRow || !selectedStoreConfigRow.storeId) return
|
|
112
|
-
|
|
113
|
-
// TODO: Here I am regretting my decision to have JSON sub object business for this
|
|
114
|
-
// Copy the store config data for uh state wackiness reasons?
|
|
115
|
-
const storeConfigRowCopy = klona(selectedStoreConfigRow)
|
|
116
|
-
// Copy the partner config row
|
|
117
|
-
const partnerConfigCopy = klona(selectedPartnerConfig)
|
|
118
|
-
|
|
119
|
-
// Copy the selectedParnterConfigStoreRows
|
|
120
|
-
let updatedStoreRows = klona(selectedPartnerConfigStoreRows)
|
|
121
|
-
|
|
122
|
-
// If empty, add storeConfigCopy
|
|
123
|
-
if (updatedStoreRows.length === 0) {
|
|
124
|
-
updatedStoreRows.push(storeConfigRowCopy)
|
|
125
|
-
} else {
|
|
126
|
-
const existingIndex = updatedStoreRows.findIndex(row => row.storeId === storeConfigRowCopy.storeId)
|
|
127
|
-
if (existingIndex === -1) {
|
|
128
|
-
updatedStoreRows.push(storeConfigRowCopy)
|
|
129
|
-
} else {
|
|
130
|
-
updatedStoreRows[existingIndex] = storeConfigRowCopy
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
// Still possible to be missing defaults?
|
|
134
|
-
if (partnerConfigCopy && partnerConfigCopy.defaults) {
|
|
135
|
-
partnerConfigCopy.defaults.store = updatedStoreRows
|
|
136
|
-
await partnerConfigurationChanged(partnerConfigCopy)
|
|
137
|
-
}
|
|
138
|
-
close()
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function close() {
|
|
142
|
-
selectedStoreConfigRow = newStoreConfig
|
|
143
|
-
show = false
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function editStoreConfigRow(row?: EcommerceStoreConfig) {
|
|
147
|
-
// Set selected row
|
|
148
|
-
selectedStoreConfigRow = klona(row || newStoreConfig)
|
|
149
|
-
|
|
150
|
-
show = true
|
|
151
|
-
}
|
|
152
|
-
</script>
|
|
153
|
-
|
|
154
|
-
<div class="card">
|
|
155
|
-
<div class="card-header">
|
|
156
|
-
<h4 class="mb-0">{translate('ecommerce.configuration.storeConfiguration', 'Store Configuration')}</h4>
|
|
157
|
-
<p class="text-muted mb-0">
|
|
158
|
-
{translate('ecommerce.configuration.configureStoreLevelEbaySettings', 'Configure store level eBay settings')}
|
|
159
|
-
</p>
|
|
160
|
-
</div>
|
|
161
|
-
<div class="card-body">
|
|
162
|
-
{#if selectedPartnerConfigStoreRows.length}
|
|
163
|
-
<Table
|
|
164
|
-
rows={selectedPartnerConfigStoreRows}
|
|
165
|
-
responsive
|
|
166
|
-
stickyHeader
|
|
167
|
-
parentClass="overflow-y-auto mh-400"
|
|
168
|
-
columns={[
|
|
169
|
-
{ property: 'storeId', name: translate('ecommerce.configuration.storeId', 'Store ID') },
|
|
170
|
-
{ property: 'name', name: translate('ecommerce.configuration.storeName', 'Store Name') },
|
|
171
|
-
{ property: 'merchantLocationKey', name: translate('ecommerce.configuration.ebayLocation', 'Ebay Location') },
|
|
172
|
-
{ property: 'active', name: translate('ecommerce.configuration.active', 'Active') },
|
|
173
|
-
]}
|
|
174
|
-
>
|
|
175
|
-
{#snippet children({ row })}
|
|
176
|
-
<tr
|
|
177
|
-
onclick={() => editStoreConfigRow(row)}
|
|
178
|
-
style="cursor: pointer;"
|
|
179
|
-
>
|
|
180
|
-
<td property="storeId">{row.storeId}</td>
|
|
181
|
-
<td property="name">{row.name}</td>
|
|
182
|
-
<td property="merchantLocationKey">{row.merchantLocationKey}</td>
|
|
183
|
-
<td property="active">{yesNo(row.active, translate)}</td>
|
|
184
|
-
</tr>
|
|
185
|
-
{/snippet}
|
|
186
|
-
</Table>
|
|
187
|
-
{/if}
|
|
188
|
-
</div>
|
|
189
|
-
<div class="card-footer">
|
|
190
|
-
<Button
|
|
191
|
-
outline
|
|
192
|
-
color="success"
|
|
193
|
-
size="sm"
|
|
194
|
-
icon="plus"
|
|
195
|
-
onclick={() => editStoreConfigRow()}
|
|
196
|
-
>
|
|
197
|
-
{translate('common:add', 'Add')}...
|
|
198
|
-
</Button>
|
|
199
|
-
</div>
|
|
200
|
-
</div>
|
|
201
|
-
<Modal
|
|
202
|
-
bind:show
|
|
203
|
-
title={translate('ecommerce.configuration.addEditStoreDefaults', 'Add/Edit Store Defaults')}
|
|
204
|
-
modalSize="lg"
|
|
205
|
-
confirmButtonText={translate('ecommerce.configuration.save', 'Save')}
|
|
206
|
-
cancelShown
|
|
207
|
-
{confirm}
|
|
208
|
-
{close}
|
|
209
|
-
>
|
|
210
|
-
{#if selectedStoreConfigRow}
|
|
211
|
-
<Checkbox
|
|
212
|
-
label={translate('ecommerce.configuration.activeOnEbay', 'Active on eBay')}
|
|
213
|
-
bind:checked={selectedStoreConfigRow.active}
|
|
214
|
-
/>
|
|
215
|
-
<div class="row mb-2">
|
|
216
|
-
<div class="col-md-6">
|
|
217
|
-
<Select
|
|
218
|
-
label={translate('ecommerce.configuration.itrackStore', 'ITrack Store')}
|
|
219
|
-
emptyText="-- {translate('ecommerce.configuration.selectStore', 'Select Store')} --"
|
|
220
|
-
bind:value={selectedStoreConfigRow.storeId}
|
|
221
|
-
>
|
|
222
|
-
{#each availableStores as store}
|
|
223
|
-
<option value={store.storeId}>{store.name}</option>
|
|
224
|
-
{/each}
|
|
225
|
-
</Select>
|
|
226
|
-
</div>
|
|
227
|
-
<div class="col-md-6">
|
|
228
|
-
{#if selectedStoreConfigRow.storeId}
|
|
229
|
-
<Select
|
|
230
|
-
label={translate('ecommerce.configuration.ebayLocation', 'eBay Location')}
|
|
231
|
-
emptyText="-- {translate('ecommerce.configuration.selectLocation', 'Select Location')} --"
|
|
232
|
-
bind:value={selectedStoreConfigRow.merchantLocationKey}
|
|
233
|
-
>
|
|
234
|
-
{#each availableLocations as location}
|
|
235
|
-
<option value={location.ebayName}>{location.ebayName}</option>
|
|
236
|
-
{/each}
|
|
237
|
-
</Select>
|
|
238
|
-
{/if}
|
|
239
|
-
</div>
|
|
240
|
-
</div>
|
|
241
|
-
{#if selectedStoreConfigRow.merchantLocationKey}
|
|
242
|
-
<EcommerceDefaults
|
|
243
|
-
bind:defaults={selectedStoreConfigRow.defaults}
|
|
244
|
-
{ebayPolicyList}
|
|
245
|
-
{ecommerceConditionList}
|
|
246
|
-
{partnerConfigurationList}
|
|
247
|
-
{selectedEcommercePartnerId}
|
|
248
|
-
/>
|
|
249
|
-
{/if}
|
|
250
|
-
{/if}
|
|
251
|
-
</Modal>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { i18n } from 'i18next'
|
|
3
|
+
|
|
4
|
+
import { getContext } from 'svelte'
|
|
5
|
+
import Table from '@isoftdata/svelte-table'
|
|
6
|
+
import { klona } from 'klona'
|
|
7
|
+
import Modal from '@isoftdata/svelte-modal'
|
|
8
|
+
import Checkbox from '@isoftdata/svelte-checkbox'
|
|
9
|
+
import Button from '@isoftdata/svelte-button'
|
|
10
|
+
import Select from '@isoftdata/svelte-select'
|
|
11
|
+
import { translate as defaultTranslate, booleanToYesNo as yesNo } from '@isoftdata/utility-string'
|
|
12
|
+
import type {
|
|
13
|
+
EbayLocation,
|
|
14
|
+
EbayPolicy,
|
|
15
|
+
EcommerceCondition,
|
|
16
|
+
EcommercePartnerConfiguration,
|
|
17
|
+
EcommerceStoreConfig,
|
|
18
|
+
Store,
|
|
19
|
+
} from './utils.js'
|
|
20
|
+
import EcommerceDefaults from './EcommerceDefaults.svelte'
|
|
21
|
+
|
|
22
|
+
const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
|
|
23
|
+
|
|
24
|
+
interface Props {
|
|
25
|
+
ebayLocationList?: Array<EbayLocation>
|
|
26
|
+
ebayPolicyList?: Array<EbayPolicy>
|
|
27
|
+
ecommerceConditionList: Array<EcommerceCondition>
|
|
28
|
+
partnerConfigurationList?: Array<EcommercePartnerConfiguration>
|
|
29
|
+
selectedEcommercePartnerId: number
|
|
30
|
+
storeList: Array<Store>
|
|
31
|
+
partnerConfigurationChanged: (partnerConfig: EcommercePartnerConfiguration) => Promise<void>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let {
|
|
35
|
+
ebayLocationList = [],
|
|
36
|
+
ebayPolicyList = [],
|
|
37
|
+
ecommerceConditionList = [],
|
|
38
|
+
partnerConfigurationList = [],
|
|
39
|
+
selectedEcommercePartnerId,
|
|
40
|
+
storeList = [],
|
|
41
|
+
partnerConfigurationChanged,
|
|
42
|
+
}: Props = $props()
|
|
43
|
+
|
|
44
|
+
let newStoreConfig: EcommerceStoreConfig = Object.freeze({
|
|
45
|
+
active: true,
|
|
46
|
+
defaults: {
|
|
47
|
+
brandMapping: undefined,
|
|
48
|
+
conditionDescription: undefined,
|
|
49
|
+
conditionId: undefined,
|
|
50
|
+
fulfillmentPolicies: undefined,
|
|
51
|
+
fulfillmentTimeUnit: undefined,
|
|
52
|
+
fulfillmentTimeValue: undefined,
|
|
53
|
+
listingDescriptionTemplate: undefined,
|
|
54
|
+
listingDuration: undefined,
|
|
55
|
+
listingFormat: undefined,
|
|
56
|
+
listingTitleTemplate: undefined,
|
|
57
|
+
manufacturerPartNumberMapping: undefined,
|
|
58
|
+
oemNumberMapping: undefined,
|
|
59
|
+
packageType: undefined,
|
|
60
|
+
paymentPolicies: undefined,
|
|
61
|
+
pricingModifier: undefined,
|
|
62
|
+
returnPolicies: undefined,
|
|
63
|
+
shippingLengthUnit: undefined,
|
|
64
|
+
shippingWeightUnit: undefined,
|
|
65
|
+
storePickupAllowed: undefined,
|
|
66
|
+
},
|
|
67
|
+
merchantLocationKey: undefined,
|
|
68
|
+
name: '',
|
|
69
|
+
storeId: 0,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
let show = $state(false)
|
|
73
|
+
let selectedStoreConfigRow = $state<EcommerceStoreConfig | null>(null)
|
|
74
|
+
|
|
75
|
+
// If we had more than one ecommercepartner, this would change depending on selected partner id
|
|
76
|
+
let selectedPartnerConfig = $derived(
|
|
77
|
+
partnerConfigurationList.find(row => row.ecommercePartnerId === selectedEcommercePartnerId),
|
|
78
|
+
)
|
|
79
|
+
// Get the store rows from the partnerconfig row
|
|
80
|
+
let selectedPartnerConfigStoreRows = $derived(selectedPartnerConfig?.defaults?.store || [])
|
|
81
|
+
|
|
82
|
+
// Filter available ebay locations depending on whether we're adding or editing
|
|
83
|
+
let availableLocations = $derived.by(() => {
|
|
84
|
+
const configuredEbayLocations = selectedPartnerConfigStoreRows.map(row => row.merchantLocationKey)
|
|
85
|
+
const isEditingExisting =
|
|
86
|
+
selectedStoreConfigRow?.name !== null &&
|
|
87
|
+
configuredEbayLocations.includes(selectedStoreConfigRow?.merchantLocationKey)
|
|
88
|
+
|
|
89
|
+
if (isEditingExisting) {
|
|
90
|
+
return ebayLocationList
|
|
91
|
+
}
|
|
92
|
+
return ebayLocationList.filter(location => !configuredEbayLocations.includes(location.ebayName))
|
|
93
|
+
})
|
|
94
|
+
// Filter available stores based on whether we're adding or editing existing
|
|
95
|
+
let availableStores = $derived.by(() => {
|
|
96
|
+
if (!selectedStoreConfigRow) return storeList
|
|
97
|
+
|
|
98
|
+
// Get the IDs of already configured stores
|
|
99
|
+
const configuredStoreIds = selectedPartnerConfigStoreRows.map(row => row.storeId)
|
|
100
|
+
const isEditingExisting =
|
|
101
|
+
selectedStoreConfigRow.storeId !== null && configuredStoreIds.includes(selectedStoreConfigRow.storeId)
|
|
102
|
+
|
|
103
|
+
if (isEditingExisting) {
|
|
104
|
+
return storeList
|
|
105
|
+
}
|
|
106
|
+
// If adding new, filter out already configured stores
|
|
107
|
+
return storeList.filter(store => !configuredStoreIds.includes(store.storeId))
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
async function confirm() {
|
|
111
|
+
if (!selectedStoreConfigRow || !selectedStoreConfigRow.storeId) return
|
|
112
|
+
|
|
113
|
+
// TODO: Here I am regretting my decision to have JSON sub object business for this
|
|
114
|
+
// Copy the store config data for uh state wackiness reasons?
|
|
115
|
+
const storeConfigRowCopy = klona(selectedStoreConfigRow)
|
|
116
|
+
// Copy the partner config row
|
|
117
|
+
const partnerConfigCopy = klona(selectedPartnerConfig)
|
|
118
|
+
|
|
119
|
+
// Copy the selectedParnterConfigStoreRows
|
|
120
|
+
let updatedStoreRows = klona(selectedPartnerConfigStoreRows)
|
|
121
|
+
|
|
122
|
+
// If empty, add storeConfigCopy
|
|
123
|
+
if (updatedStoreRows.length === 0) {
|
|
124
|
+
updatedStoreRows.push(storeConfigRowCopy)
|
|
125
|
+
} else {
|
|
126
|
+
const existingIndex = updatedStoreRows.findIndex(row => row.storeId === storeConfigRowCopy.storeId)
|
|
127
|
+
if (existingIndex === -1) {
|
|
128
|
+
updatedStoreRows.push(storeConfigRowCopy)
|
|
129
|
+
} else {
|
|
130
|
+
updatedStoreRows[existingIndex] = storeConfigRowCopy
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Still possible to be missing defaults?
|
|
134
|
+
if (partnerConfigCopy && partnerConfigCopy.defaults) {
|
|
135
|
+
partnerConfigCopy.defaults.store = updatedStoreRows
|
|
136
|
+
await partnerConfigurationChanged(partnerConfigCopy)
|
|
137
|
+
}
|
|
138
|
+
close()
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function close() {
|
|
142
|
+
selectedStoreConfigRow = newStoreConfig
|
|
143
|
+
show = false
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function editStoreConfigRow(row?: EcommerceStoreConfig) {
|
|
147
|
+
// Set selected row
|
|
148
|
+
selectedStoreConfigRow = klona(row || newStoreConfig)
|
|
149
|
+
|
|
150
|
+
show = true
|
|
151
|
+
}
|
|
152
|
+
</script>
|
|
153
|
+
|
|
154
|
+
<div class="card">
|
|
155
|
+
<div class="card-header">
|
|
156
|
+
<h4 class="mb-0">{translate('ecommerce.configuration.storeConfiguration', 'Store Configuration')}</h4>
|
|
157
|
+
<p class="text-muted mb-0">
|
|
158
|
+
{translate('ecommerce.configuration.configureStoreLevelEbaySettings', 'Configure store level eBay settings')}
|
|
159
|
+
</p>
|
|
160
|
+
</div>
|
|
161
|
+
<div class="card-body">
|
|
162
|
+
{#if selectedPartnerConfigStoreRows.length}
|
|
163
|
+
<Table
|
|
164
|
+
rows={selectedPartnerConfigStoreRows}
|
|
165
|
+
responsive
|
|
166
|
+
stickyHeader
|
|
167
|
+
parentClass="overflow-y-auto mh-400"
|
|
168
|
+
columns={[
|
|
169
|
+
{ property: 'storeId', name: translate('ecommerce.configuration.storeId', 'Store ID') },
|
|
170
|
+
{ property: 'name', name: translate('ecommerce.configuration.storeName', 'Store Name') },
|
|
171
|
+
{ property: 'merchantLocationKey', name: translate('ecommerce.configuration.ebayLocation', 'Ebay Location') },
|
|
172
|
+
{ property: 'active', name: translate('ecommerce.configuration.active', 'Active') },
|
|
173
|
+
]}
|
|
174
|
+
>
|
|
175
|
+
{#snippet children({ row })}
|
|
176
|
+
<tr
|
|
177
|
+
onclick={() => editStoreConfigRow(row)}
|
|
178
|
+
style="cursor: pointer;"
|
|
179
|
+
>
|
|
180
|
+
<td property="storeId">{row.storeId}</td>
|
|
181
|
+
<td property="name">{row.name}</td>
|
|
182
|
+
<td property="merchantLocationKey">{row.merchantLocationKey}</td>
|
|
183
|
+
<td property="active">{yesNo(row.active, translate)}</td>
|
|
184
|
+
</tr>
|
|
185
|
+
{/snippet}
|
|
186
|
+
</Table>
|
|
187
|
+
{/if}
|
|
188
|
+
</div>
|
|
189
|
+
<div class="card-footer">
|
|
190
|
+
<Button
|
|
191
|
+
outline
|
|
192
|
+
color="success"
|
|
193
|
+
size="sm"
|
|
194
|
+
icon="plus"
|
|
195
|
+
onclick={() => editStoreConfigRow()}
|
|
196
|
+
>
|
|
197
|
+
{translate('common:add', 'Add')}...
|
|
198
|
+
</Button>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<Modal
|
|
202
|
+
bind:show
|
|
203
|
+
title={translate('ecommerce.configuration.addEditStoreDefaults', 'Add/Edit Store Defaults')}
|
|
204
|
+
modalSize="lg"
|
|
205
|
+
confirmButtonText={translate('ecommerce.configuration.save', 'Save')}
|
|
206
|
+
cancelShown
|
|
207
|
+
{confirm}
|
|
208
|
+
{close}
|
|
209
|
+
>
|
|
210
|
+
{#if selectedStoreConfigRow}
|
|
211
|
+
<Checkbox
|
|
212
|
+
label={translate('ecommerce.configuration.activeOnEbay', 'Active on eBay')}
|
|
213
|
+
bind:checked={selectedStoreConfigRow.active}
|
|
214
|
+
/>
|
|
215
|
+
<div class="row mb-2">
|
|
216
|
+
<div class="col-md-6">
|
|
217
|
+
<Select
|
|
218
|
+
label={translate('ecommerce.configuration.itrackStore', 'ITrack Store')}
|
|
219
|
+
emptyText="-- {translate('ecommerce.configuration.selectStore', 'Select Store')} --"
|
|
220
|
+
bind:value={selectedStoreConfigRow.storeId}
|
|
221
|
+
>
|
|
222
|
+
{#each availableStores as store}
|
|
223
|
+
<option value={store.storeId}>{store.name}</option>
|
|
224
|
+
{/each}
|
|
225
|
+
</Select>
|
|
226
|
+
</div>
|
|
227
|
+
<div class="col-md-6">
|
|
228
|
+
{#if selectedStoreConfigRow.storeId}
|
|
229
|
+
<Select
|
|
230
|
+
label={translate('ecommerce.configuration.ebayLocation', 'eBay Location')}
|
|
231
|
+
emptyText="-- {translate('ecommerce.configuration.selectLocation', 'Select Location')} --"
|
|
232
|
+
bind:value={selectedStoreConfigRow.merchantLocationKey}
|
|
233
|
+
>
|
|
234
|
+
{#each availableLocations as location}
|
|
235
|
+
<option value={location.ebayName}>{location.ebayName}</option>
|
|
236
|
+
{/each}
|
|
237
|
+
</Select>
|
|
238
|
+
{/if}
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
{#if selectedStoreConfigRow.merchantLocationKey}
|
|
242
|
+
<EcommerceDefaults
|
|
243
|
+
bind:defaults={selectedStoreConfigRow.defaults}
|
|
244
|
+
{ebayPolicyList}
|
|
245
|
+
{ecommerceConditionList}
|
|
246
|
+
{partnerConfigurationList}
|
|
247
|
+
{selectedEcommercePartnerId}
|
|
248
|
+
/>
|
|
249
|
+
{/if}
|
|
250
|
+
{/if}
|
|
251
|
+
</Modal>
|
package/dist/PolicyList.svelte
CHANGED
|
@@ -1,54 +1,53 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { i18n } from 'i18next'
|
|
3
|
-
|
|
4
|
-
import { getContext } from 'svelte'
|
|
5
|
-
|
|
6
|
-
import Table, { Td } from '@isoftdata/svelte-table'
|
|
7
|
-
import Checkbox from '@isoftdata/svelte-checkbox'
|
|
8
|
-
import { translate as defaultTranslate } from '@isoftdata/utility-string'
|
|
9
|
-
|
|
10
|
-
const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
|
|
11
|
-
|
|
12
|
-
import type { PolicyRowWithChecked } from './utils.js'
|
|
13
|
-
|
|
14
|
-
interface Props {
|
|
15
|
-
title: string
|
|
16
|
-
policies: Array<PolicyRowWithChecked>
|
|
17
|
-
selectedPolicyIds: Array<string>
|
|
18
|
-
onSelectionChange: (selectedIds: Array<string>) => void
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
let { title, policies, selectedPolicyIds, onSelectionChange }: Props = $props()
|
|
22
|
-
|
|
23
|
-
function handleCheckboxChange(policy: PolicyRowWithChecked, checked: boolean) {
|
|
24
|
-
const updatedIds = new Set<string>(selectedPolicyIds)
|
|
25
|
-
checked ? updatedIds.add(policy.policyId) : updatedIds.delete(policy.policyId)
|
|
26
|
-
onSelectionChange(Array.from(updatedIds))
|
|
27
|
-
}
|
|
28
|
-
</script>
|
|
29
|
-
|
|
30
|
-
<div class="mb-4">
|
|
31
|
-
<Table
|
|
32
|
-
responsive
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{ property: '
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
</
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { i18n } from 'i18next'
|
|
3
|
+
|
|
4
|
+
import { getContext } from 'svelte'
|
|
5
|
+
|
|
6
|
+
import Table, { Td } from '@isoftdata/svelte-table'
|
|
7
|
+
import Checkbox from '@isoftdata/svelte-checkbox'
|
|
8
|
+
import { translate as defaultTranslate } from '@isoftdata/utility-string'
|
|
9
|
+
|
|
10
|
+
const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
|
|
11
|
+
|
|
12
|
+
import type { PolicyRowWithChecked } from './utils.js'
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
title: string
|
|
16
|
+
policies: Array<PolicyRowWithChecked>
|
|
17
|
+
selectedPolicyIds: Array<string>
|
|
18
|
+
onSelectionChange: (selectedIds: Array<string>) => void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let { title, policies, selectedPolicyIds, onSelectionChange }: Props = $props()
|
|
22
|
+
|
|
23
|
+
function handleCheckboxChange(policy: PolicyRowWithChecked, checked: boolean) {
|
|
24
|
+
const updatedIds = new Set<string>(selectedPolicyIds)
|
|
25
|
+
checked ? updatedIds.add(policy.policyId) : updatedIds.delete(policy.policyId)
|
|
26
|
+
onSelectionChange(Array.from(updatedIds))
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div class="mb-4">
|
|
31
|
+
<Table
|
|
32
|
+
responsive
|
|
33
|
+
stickyHeader
|
|
34
|
+
rows={policies}
|
|
35
|
+
parentClass="overflow-y-auto mh-500"
|
|
36
|
+
columns={[
|
|
37
|
+
{ property: 'checked', name: translate('configuration.ecommerce.selected', 'Selected'), width: '100px' },
|
|
38
|
+
{ property: 'name', name: title, defaultSortColumn: true }, // translated before passing to component
|
|
39
|
+
]}
|
|
40
|
+
>
|
|
41
|
+
{#snippet children({ row })}
|
|
42
|
+
<tr>
|
|
43
|
+
<Td property="checked">
|
|
44
|
+
<Checkbox
|
|
45
|
+
checked={row.checked}
|
|
46
|
+
onchange={e => handleCheckboxChange(row, e.currentTarget.checked)}
|
|
47
|
+
/>
|
|
48
|
+
</Td>
|
|
49
|
+
<td>{row.name}</td>
|
|
50
|
+
</tr>
|
|
51
|
+
{/snippet}
|
|
52
|
+
</Table>
|
|
53
|
+
</div>
|
|
@@ -1,9 +1,27 @@
|
|
|
1
|
-
import type { BuildEbayListingInput, FileItem, ImageUrl, InventoryListingDetail, NewInventoryListingDetail } from '../utils.js';
|
|
1
|
+
import type { BuildEbayListingInput, EcommerceSharedDefaults, FileItem, ImageUrl, InventoryListingDetail, InventoryRow, NewInventoryListingDetail } from '../utils.js';
|
|
2
2
|
/**
|
|
3
3
|
* Shared method for creating an inventorylistingdetail row
|
|
4
4
|
* Includes minimum validation and may return undefined if certain configuration settings determine the inventory item doesn't get a listing created
|
|
5
5
|
*/
|
|
6
6
|
export declare const buildEbayListing: (buildEbayListingInput: BuildEbayListingInput) => InventoryListingDetail | NewInventoryListingDetail | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Computes the adjusted price for a listing based on the following priority:
|
|
9
|
+
* 1. If existingListingPrice is set (not null/undefined/0), return it as-is (user has manually adjusted)
|
|
10
|
+
* 2. Otherwise, determine base price from defaultPriceType in priority order:
|
|
11
|
+
* - partTypeDefaults.defaultPriceType
|
|
12
|
+
* - storeDefaults.defaultPriceType
|
|
13
|
+
* - globalDefaults.defaultPriceType
|
|
14
|
+
* - Ultimate fallback: inventoryRow.retailPrice
|
|
15
|
+
* 3. Apply pricingModifier (with same priority fallback, default 100 = no change)
|
|
16
|
+
* 4. Formula: basePrice * (pricingModifier / 100)
|
|
17
|
+
*/
|
|
18
|
+
export declare const computeAdjustedPrice: ({ existingListingPrice, partTypeDefaults, storeDefaults, globalDefaults, inventoryRow, }: {
|
|
19
|
+
existingListingPrice: number | null | undefined;
|
|
20
|
+
partTypeDefaults: EcommerceSharedDefaults | null | undefined;
|
|
21
|
+
storeDefaults: EcommerceSharedDefaults | null | undefined;
|
|
22
|
+
globalDefaults: EcommerceSharedDefaults | null | undefined;
|
|
23
|
+
inventoryRow: InventoryRow;
|
|
24
|
+
}) => number | null;
|
|
7
25
|
/**
|
|
8
26
|
* Accepts:
|
|
9
27
|
* the raw string of imageUrls from the listing, should be stringified json
|