Add support for per-item default discount, for new custorder

This commit is contained in:
Lance Edgar 2023-01-11 10:29:36 -06:00
parent dfa4178204
commit b8389c72bb
4 changed files with 72 additions and 8 deletions

View file

@ -891,6 +891,8 @@ class Form(object):
return json.dumps({'name': value['filename']}) return json.dumps({'name': value['filename']})
return 'null' return 'null'
app = self.request.rattail_config.get_app()
value = app.json_friendly(value)
return json.dumps(value) return json.dumps(value)
def get_error_messages(self, field): def get_error_messages(self, field):

View file

@ -97,6 +97,29 @@
</b-checkbox> </b-checkbox>
</b-field> </b-field>
<b-field>
<b-checkbox name="rattail.custorders.allow_item_discounts_if_on_sale"
v-model="simpleSettings['rattail.custorders.allow_item_discounts_if_on_sale']"
native-value="true"
@input="settingsNeedSaved = true"
:disabled="!simpleSettings['rattail.custorders.allow_item_discounts']">
Allow discount even if item is on sale
</b-checkbox>
</b-field>
<div class="level-left block">
<div class="level-item">Default item discount</div>
<div class="level-item">
<b-input name="rattail.custorders.default_item_discount"
v-model="simpleSettings['rattail.custorders.default_item_discount']"
@input="settingsNeedSaved = true"
style="width: 5rem;"
:disabled="!simpleSettings['rattail.custorders.allow_item_discounts']">
</b-input>
</div>
<div class="level-item">%</div>
</div>
<b-field> <b-field>
<b-checkbox name="rattail.custorders.allow_past_item_reorder" <b-checkbox name="rattail.custorders.allow_past_item_reorder"
v-model="simpleSettings['rattail.custorders.allow_past_item_reorder']" v-model="simpleSettings['rattail.custorders.allow_past_item_reorder']"

View file

@ -792,7 +792,8 @@
<b-field grouped> <b-field grouped>
<b-field label="Quantity" horizontal> <b-field label="Quantity" horizontal>
<numeric-input v-model="productQuantity"> <numeric-input v-model="productQuantity"
style="width: 5rem;">
</numeric-input> </numeric-input>
</b-field> </b-field>
@ -812,7 +813,8 @@
<div class="level"> <div class="level">
<div class="level-item"> <div class="level-item">
<numeric-input v-model="productDiscountPercent" <numeric-input v-model="productDiscountPercent"
style="width: 5rem;"> style="width: 5rem;"
:disabled="!allowItemDiscount">
</numeric-input> </numeric-input>
</div> </div>
<div class="level-item"> <div class="level-item">
@ -1238,7 +1240,8 @@
% endif % endif
% if allow_item_discounts: % if allow_item_discounts:
productDiscountPercent: null, productDiscountPercent: ${json.dumps(default_item_discount)|n},
allowDiscountsIfOnSale: ${json.dumps(allow_item_discounts_if_on_sale)|n},
% endif % endif
pendingProduct: {}, pendingProduct: {},
@ -1421,6 +1424,19 @@
return text return text
}, },
% if allow_item_discounts:
allowItemDiscount() {
if (!this.allowDiscountsIfOnSale) {
if (this.productSalePriceDisplay) {
return false
}
}
return true
},
% endif
itemDialogSaveDisabled() { itemDialogSaveDisabled() {
if (this.itemDialogSaving) { if (this.itemDialogSaving) {
return true return true
@ -1912,7 +1928,7 @@
% endif % endif
% if allow_item_discounts: % if allow_item_discounts:
this.productDiscountPercent = null this.productDiscountPercent = ${json.dumps(default_item_discount)|n}
% endif % endif
this.itemDialogTabIndex = 0 this.itemDialogTabIndex = 0
@ -2060,6 +2076,10 @@
this.productImageURL = null this.productImageURL = null
this.productUnitChoices = this.defaultUnitChoices this.productUnitChoices = this.defaultUnitChoices
% if allow_item_discounts:
this.productDiscountPercent = ${json.dumps(default_item_discount)|n}
% endif
% if product_price_may_be_questionable: % if product_price_may_be_questionable:
this.productPriceNeedsConfirmation = false this.productPriceNeedsConfirmation = false
% endif % endif
@ -2106,6 +2126,11 @@
this.productSalePrice = response.data.sale_price this.productSalePrice = response.data.sale_price
this.productSalePriceDisplay = response.data.sale_price_display this.productSalePriceDisplay = response.data.sale_price_display
this.productSaleEndsDisplay = response.data.sale_ends_display this.productSaleEndsDisplay = response.data.sale_ends_display
% if allow_item_discounts:
this.productDiscountPercent = this.allowItemDiscount ? response.data.default_item_discount : null
% endif
this.productURL = response.data.url this.productURL = response.data.url
this.productImageURL = response.data.image_url this.productImageURL = response.data.image_url
this.setProductUnitChoices(response.data.uom_choices) this.setProductUnitChoices(response.data.uom_choices)

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2022 Lance Edgar # Copyright © 2010-2023 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -293,6 +293,7 @@ class CustomerOrderView(MasterView):
submits the order, at which point the batch is converted to a proper submits the order, at which point the batch is converted to a proper
order. order.
""" """
app = self.get_rattail_app()
# TODO: deprecate / remove this # TODO: deprecate / remove this
self.handler = self.batch_handler self.handler = self.batch_handler
batch = self.get_current_batch() batch = self.get_current_batch()
@ -349,6 +350,10 @@ class CustomerOrderView(MasterView):
'default_uom_choices': self.batch_handler.uom_choices_for_product(None), 'default_uom_choices': self.batch_handler.uom_choices_for_product(None),
'default_uom': None, 'default_uom': None,
'allow_item_discounts': self.batch_handler.allow_item_discounts(), 'allow_item_discounts': self.batch_handler.allow_item_discounts(),
'allow_item_discounts_if_on_sale': self.batch_handler.allow_item_discounts_if_on_sale(),
# nb. render quantity so that '10.0' => '10'
'default_item_discount': app.render_quantity(
self.batch_handler.get_default_item_discount()),
'allow_past_item_reorder': self.batch_handler.allow_past_item_reorder(), 'allow_past_item_reorder': self.batch_handler.allow_past_item_reorder(),
}) })
@ -633,9 +638,11 @@ class CustomerOrderView(MasterView):
return {'error': six.text_type(error)} return {'error': six.text_type(error)}
else: else:
info['url'] = self.request.route_url('products.view', uuid=info['uuid']) info['url'] = self.request.route_url('products.view', uuid=info['uuid'])
return info app = self.get_rattail_app()
return app.json_friendly(info)
def get_past_items(self, batch, data): def get_past_items(self, batch, data):
app = self.get_rattail_app()
past_products = self.batch_handler.get_past_products(batch) past_products = self.batch_handler.get_past_products(batch)
past_items = [] past_items = []
@ -646,6 +653,7 @@ class CustomerOrderView(MasterView):
# nb. handler may raise error if product is "unsupported" # nb. handler may raise error if product is "unsupported"
pass pass
else: else:
item = app.json_friendly(item)
past_items.append(item) past_items.append(item)
return {'past_items': past_items} return {'past_items': past_items}
@ -987,6 +995,12 @@ class CustomerOrderView(MasterView):
{'section': 'rattail.custorders', {'section': 'rattail.custorders',
'option': 'allow_item_discounts', 'option': 'allow_item_discounts',
'type': bool}, 'type': bool},
{'section': 'rattail.custorders',
'option': 'allow_item_discounts_if_on_sale',
'type': bool},
{'section': 'rattail.custorders',
'option': 'default_item_discount',
'type': float},
{'section': 'rattail.custorders', {'section': 'rattail.custorders',
'option': 'allow_past_item_reorder', 'option': 'allow_past_item_reorder',
'type': bool}, 'type': bool},