-
Couldn't load subscription status.
- Fork 13
Price component #362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Price component #362
Changes from all commits
c4695f6
ca4152e
e7a6d11
c877353
959237d
0573295
2f49d60
62a26fa
539a3f2
b01db37
3828e88
898cdb2
4613d45
fb8d091
4263d58
1abbbc1
715ca93
ecbd7e0
9d9b943
f59d1bc
bb6ee89
ce99948
6cc9ec2
60d4399
f8ec3b7
5f19e9d
20e6679
2b11f2f
7b61253
18ce4d6
43d3a57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| <script> | ||
| export default { | ||
| props: { | ||
| product: { | ||
| type: Object, | ||
| default: () => config.product || {}, | ||
| }, | ||
| location: { | ||
| type: String, | ||
| default: 'catalog', | ||
| }, | ||
| options: { | ||
| type: Object, | ||
| default: () => ({}), | ||
| }, | ||
| }, | ||
| render() { | ||
| return this.$scopedSlots.default(this) | ||
| }, | ||
| methods: { | ||
| calculatePrice(options = null) { | ||
| options ??= this.options | ||
| let product = options?.product || this.product | ||
| let location = options?.location || this.location | ||
| let special_price = options.special_price ?? false | ||
| let displayTax = this.$root.includeTaxAt(location) | ||
| let price = options?.price || (special_price ? product.special_price ?? product.price ?? 0 : product.price ?? 0) * 1 | ||
| if (options.tier_price) { | ||
| price = options.tier_price.price * 1 | ||
| } | ||
| if (options.product_options) { | ||
| price += this.calculateOptionsValue(price, product, options.product_options) | ||
| } | ||
| let taxMultiplier = this.getTaxPercent(product) + 1 | ||
| return price | ||
| // Tax calculation can be done from the backend right? | ||
| if (window.config.tax.calculation.price_includes_tax) { | ||
| if (displayTax) { | ||
| return price | ||
| } else { | ||
| return price / taxMultiplier | ||
| } | ||
| } else { | ||
| if (displayTax) { | ||
| return price * taxMultiplier | ||
| } else { | ||
| return price | ||
| } | ||
| } | ||
| }, | ||
| getTaxPercent(product) { | ||
| let country_id = window.config.tax.defaults.country_id | ||
| let region_id = window.config.tax.defaults.region_id | ||
| let postcode = window.config.tax.defaults.postcode | ||
| if (['shipping', 'billing'].includes(window.config?.tax?.calculation.based_on)) { | ||
| country_id = window.app?.$data?.checkout?.[window.config?.tax?.calculation.based_on + '_address']?.country_id || country_id | ||
| region_id = window.app?.$data?.checkout?.[window.config?.tax?.calculation.based_on + '_address']?.region_id || region_id | ||
| postcode = window.app?.$data?.checkout?.[window.config?.tax?.calculation.based_on + '_address']?.postcode || postcode | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let basedOn = window.app?.$data?.checkout?.[window.config?.tax?.calculation.based_on + '_address']And then use that instead of repeating it 3 times, would probably be much cleaner here. |
||
| } | ||
| let taxRate = window.config.tax.rates?.[product.tax_class_id]?.find( | ||
| (rate) => | ||
| rate.tax_country_id === country_id && | ||
| rate.tax_region_id * 1 === region_id * 1 && | ||
| postcode.match('^' + rate.tax_postcode.replace('*', '.*') + '$'), | ||
| )?.rate | ||
| if (taxRate === undefined || taxRate === null) { | ||
| console.debug('No tax rates found for', product, country_id, region_id, postcode) | ||
| } | ||
| return (taxRate ?? 0) / 100 | ||
| }, | ||
| calculateOptionsValue(basePrice, product, customOptions) { | ||
| return Object.entries(customOptions).reduce((priceAddition, [key, val]) => { | ||
| if (!val) { | ||
| return priceAddition | ||
| } | ||
| let option = product.options.find((option) => option.option_id == key) | ||
| let optionPrice = ['drop_down', 'radio'].includes(option.type) | ||
| ? option.values.find((value) => value.option_type_id == val).price | ||
| : option.price | ||
| if (optionPrice.price_type == 'fixed') { | ||
| return priceAddition * 1 + parseFloat(optionPrice.price) | ||
| } | ||
| return priceAddition * 1 + (parseFloat(basePrice) * parseFloat(optionPrice.price)) / 100 | ||
| }, 0) | ||
| }, | ||
| }, | ||
| computed: { | ||
| specialPrice() { | ||
| JSON.stringify(this.options) // Hack: make vue recognize reactivity within the options object | ||
| return this.calculatePrice({ ...this.options, ...{ special_price: true } }) | ||
| }, | ||
| price() { | ||
| return this.calculatePrice(this.options) | ||
| }, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to be thought out again, Magento doesn't work with prices this way. Prices are calculated as follows: Note that prices are clamped to a minimum of 0 before and after the custom options are added. Also, the price gets rounded before getting multiplied by the qty. |
||
| isDiscounted() { | ||
| return this.specialPrice != this.price | ||
| }, | ||
| range() { | ||
| if (!this.product.super_attributes) { | ||
| return null | ||
| } | ||
| let prices = Object.values(this.product.children).map((child) => | ||
| this.calculatePrice({ ...this.option, ...{ special_price: true, product: child } }), | ||
| ) | ||
| return { | ||
| min: Math.min(...prices), | ||
| max: Math.max(...prices), | ||
| } | ||
| }, | ||
| includesTax() { | ||
| return this.$root.includeTaxAt(this.location) | ||
| }, | ||
| }, | ||
| } | ||
| </script> | ||
Uh oh!
There was an error while loading. Please reload this page.