Add basic per-item discount support for custorders
This commit is contained in:
parent
b37f63a231
commit
2950827c63
|
@ -88,6 +88,15 @@
|
||||||
</b-checkbox>
|
</b-checkbox>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
|
<b-field>
|
||||||
|
<b-checkbox name="rattail.custorders.allow_item_discounts"
|
||||||
|
v-model="simpleSettings['rattail.custorders.allow_item_discounts']"
|
||||||
|
native-value="true"
|
||||||
|
@input="settingsNeedSaved = true">
|
||||||
|
Allow per-item discounts
|
||||||
|
</b-checkbox>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
|
@ -805,7 +805,21 @@
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field grouped>
|
<b-field grouped>
|
||||||
<b-field label="Total Price">
|
% if allow_item_discounts:
|
||||||
|
<b-field label="Discount" horizontal>
|
||||||
|
<div class="level">
|
||||||
|
<div class="level-item">
|
||||||
|
<numeric-input v-model="productDiscountPercent"
|
||||||
|
style="width: 5rem;">
|
||||||
|
</numeric-input>
|
||||||
|
</div>
|
||||||
|
<div class="level-item">
|
||||||
|
<span> %</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-field>
|
||||||
|
% endif
|
||||||
|
<b-field label="Total Price" horizontal expanded>
|
||||||
<span :class="productSalePriceDisplay ? 'has-background-warning': null">
|
<span :class="productSalePriceDisplay ? 'has-background-warning': null">
|
||||||
{{ getItemTotalPriceDisplay() }}
|
{{ getItemTotalPriceDisplay() }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -981,6 +995,12 @@
|
||||||
</span>
|
</span>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
|
||||||
|
% if allow_item_discounts:
|
||||||
|
<b-table-column label="Discount">
|
||||||
|
{{ props.row.discount_percent }}{{ props.row.discount_percent ? " %" : "" }}
|
||||||
|
</b-table-column>
|
||||||
|
% endif
|
||||||
|
|
||||||
<b-table-column label="Total">
|
<b-table-column label="Total">
|
||||||
<span
|
<span
|
||||||
% if product_price_may_be_questionable:
|
% if product_price_may_be_questionable:
|
||||||
|
@ -1099,6 +1119,7 @@
|
||||||
items: ${json.dumps(order_items)|n},
|
items: ${json.dumps(order_items)|n},
|
||||||
editingItem: null,
|
editingItem: null,
|
||||||
showingItemDialog: false,
|
showingItemDialog: false,
|
||||||
|
itemDialogSaving: false,
|
||||||
itemDialogTabIndex: 0,
|
itemDialogTabIndex: 0,
|
||||||
pastItemsShowDialog: false,
|
pastItemsShowDialog: false,
|
||||||
pastItemsLoading: false,
|
pastItemsLoading: false,
|
||||||
|
@ -1133,6 +1154,10 @@
|
||||||
productPriceNeedsConfirmation: false,
|
productPriceNeedsConfirmation: false,
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
% if allow_item_discounts:
|
||||||
|
productDiscountPercent: null,
|
||||||
|
% endif
|
||||||
|
|
||||||
pendingProduct: {},
|
pendingProduct: {},
|
||||||
departmentOptions: ${json.dumps(department_options)|n},
|
departmentOptions: ${json.dumps(department_options)|n},
|
||||||
|
|
||||||
|
@ -1314,6 +1339,9 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
itemDialogSaveDisabled() {
|
itemDialogSaveDisabled() {
|
||||||
|
if (this.itemDialogSaving) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if (this.productIsKnown) {
|
if (this.productIsKnown) {
|
||||||
if (!this.productUUID) {
|
if (!this.productUUID) {
|
||||||
return true
|
return true
|
||||||
|
@ -1330,6 +1358,9 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
itemDialogSaveButtonText() {
|
itemDialogSaveButtonText() {
|
||||||
|
if (this.itemDialogSaving) {
|
||||||
|
return "Working, please wait..."
|
||||||
|
}
|
||||||
return this.editingItem ? "Update Item" : "Add Item"
|
return this.editingItem ? "Update Item" : "Add Item"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1723,6 +1754,11 @@
|
||||||
if (basePrice) {
|
if (basePrice) {
|
||||||
let totalPrice = basePrice * this.productQuantity
|
let totalPrice = basePrice * this.productQuantity
|
||||||
if (totalPrice) {
|
if (totalPrice) {
|
||||||
|
% if allow_item_discounts:
|
||||||
|
if (this.productDiscountPercent) {
|
||||||
|
totalPrice *= (100 - this.productDiscountPercent) / 100
|
||||||
|
}
|
||||||
|
% endif
|
||||||
totalPrice = totalPrice.toFixed(2)
|
totalPrice = totalPrice.toFixed(2)
|
||||||
return "$" + totalPrice
|
return "$" + totalPrice
|
||||||
}
|
}
|
||||||
|
@ -1790,6 +1826,10 @@
|
||||||
this.productPriceNeedsConfirmation = false
|
this.productPriceNeedsConfirmation = false
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
% if allow_item_discounts:
|
||||||
|
this.productDiscountPercent = null
|
||||||
|
% endif
|
||||||
|
|
||||||
this.itemDialogTabIndex = 0
|
this.itemDialogTabIndex = 0
|
||||||
this.showingItemDialog = true
|
this.showingItemDialog = true
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
@ -1882,6 +1922,10 @@
|
||||||
this.productUnitChoices = row.order_uom_choices
|
this.productUnitChoices = row.order_uom_choices
|
||||||
this.productUOM = row.order_uom
|
this.productUOM = row.order_uom
|
||||||
|
|
||||||
|
% if allow_item_discounts:
|
||||||
|
this.productDiscountPercent = row.discount_percent
|
||||||
|
% endif
|
||||||
|
|
||||||
this.itemDialogTabIndex = 1
|
this.itemDialogTabIndex = 1
|
||||||
this.showingItemDialog = true
|
this.showingItemDialog = true
|
||||||
},
|
},
|
||||||
|
@ -1992,6 +2036,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
itemDialogSave() {
|
itemDialogSave() {
|
||||||
|
this.itemDialogSaving = true
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
product_is_known: this.productIsKnown,
|
product_is_known: this.productIsKnown,
|
||||||
|
@ -2002,6 +2047,10 @@
|
||||||
order_uom: this.productUOM,
|
order_uom: this.productUOM,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
% if allow_item_discounts:
|
||||||
|
params.discount_percent = this.productDiscountPercent
|
||||||
|
% endif
|
||||||
|
|
||||||
if (this.productIsKnown) {
|
if (this.productIsKnown) {
|
||||||
params.product_uuid = this.productUUID
|
params.product_uuid = this.productUUID
|
||||||
} else {
|
} else {
|
||||||
|
@ -2032,6 +2081,7 @@
|
||||||
// also update the batch total price
|
// also update the batch total price
|
||||||
this.batchTotalPriceDisplay = response.data.batch.total_price_display
|
this.batchTotalPriceDisplay = response.data.batch.total_price_display
|
||||||
|
|
||||||
|
this.itemDialogSaving = false
|
||||||
this.showingItemDialog = false
|
this.showingItemDialog = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -348,6 +348,7 @@ class CustomerOrderView(MasterView):
|
||||||
'department_options': self.get_department_options(),
|
'department_options': self.get_department_options(),
|
||||||
'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(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.batch_handler.allow_case_orders():
|
if self.batch_handler.allow_case_orders():
|
||||||
|
@ -695,6 +696,7 @@ class CustomerOrderView(MasterView):
|
||||||
'order_quantity': pretty_quantity(row.order_quantity),
|
'order_quantity': pretty_quantity(row.order_quantity),
|
||||||
'order_uom': row.order_uom,
|
'order_uom': row.order_uom,
|
||||||
'order_uom_choices': self.uom_choices_for_row(row),
|
'order_uom_choices': self.uom_choices_for_row(row),
|
||||||
|
'discount_percent': pretty_quantity(row.discount_percent),
|
||||||
|
|
||||||
'department_display': row.department_name,
|
'department_display': row.department_name,
|
||||||
|
|
||||||
|
@ -807,6 +809,7 @@ class CustomerOrderView(MasterView):
|
||||||
|
|
||||||
order_quantity = decimal.Decimal(data.get('order_quantity') or '0')
|
order_quantity = decimal.Decimal(data.get('order_quantity') or '0')
|
||||||
order_uom = data.get('order_uom')
|
order_uom = data.get('order_uom')
|
||||||
|
discount_percent = decimal.Decimal(data.get('discount_percent') or '0')
|
||||||
|
|
||||||
if data.get('product_is_known'):
|
if data.get('product_is_known'):
|
||||||
|
|
||||||
|
@ -822,6 +825,9 @@ class CustomerOrderView(MasterView):
|
||||||
if self.batch_handler.product_price_may_be_questionable():
|
if self.batch_handler.product_price_may_be_questionable():
|
||||||
kwargs['price_needs_confirmation'] = data.get('price_needs_confirmation')
|
kwargs['price_needs_confirmation'] = data.get('price_needs_confirmation')
|
||||||
|
|
||||||
|
if self.batch_handler.allow_item_discounts():
|
||||||
|
kwargs['discount_percent'] = discount_percent
|
||||||
|
|
||||||
row = self.batch_handler.add_product(batch, product,
|
row = self.batch_handler.add_product(batch, product,
|
||||||
order_quantity, order_uom,
|
order_quantity, order_uom,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
@ -838,9 +844,14 @@ class CustomerOrderView(MasterView):
|
||||||
|
|
||||||
pending_info['user'] = self.request.user
|
pending_info['user'] = self.request.user
|
||||||
|
|
||||||
|
kwargs = {}
|
||||||
|
if self.batch_handler.allow_item_discounts():
|
||||||
|
kwargs['discount_percent'] = discount_percent
|
||||||
|
|
||||||
row = self.batch_handler.add_pending_product(batch,
|
row = self.batch_handler.add_pending_product(batch,
|
||||||
pending_info,
|
pending_info,
|
||||||
order_quantity, order_uom)
|
order_quantity, order_uom,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
self.Session.flush()
|
self.Session.flush()
|
||||||
return {'batch': self.normalize_batch(batch),
|
return {'batch': self.normalize_batch(batch),
|
||||||
|
@ -860,6 +871,7 @@ class CustomerOrderView(MasterView):
|
||||||
|
|
||||||
order_quantity = decimal.Decimal(data.get('order_quantity') or '0')
|
order_quantity = decimal.Decimal(data.get('order_quantity') or '0')
|
||||||
order_uom = data.get('order_uom')
|
order_uom = data.get('order_uom')
|
||||||
|
discount_percent = decimal.Decimal(data.get('discount_percent') or '0')
|
||||||
|
|
||||||
if data.get('product_is_known'):
|
if data.get('product_is_known'):
|
||||||
|
|
||||||
|
@ -879,6 +891,9 @@ class CustomerOrderView(MasterView):
|
||||||
if self.batch_handler.product_price_may_be_questionable():
|
if self.batch_handler.product_price_may_be_questionable():
|
||||||
row.price_needs_confirmation = data.get('price_needs_confirmation')
|
row.price_needs_confirmation = data.get('price_needs_confirmation')
|
||||||
|
|
||||||
|
if self.batch_handler.allow_item_discounts():
|
||||||
|
row.discount_percent = discount_percent
|
||||||
|
|
||||||
self.batch_handler.refresh_row(row)
|
self.batch_handler.refresh_row(row)
|
||||||
|
|
||||||
else: # product is not known
|
else: # product is not known
|
||||||
|
@ -887,6 +902,9 @@ class CustomerOrderView(MasterView):
|
||||||
row.order_quantity = order_quantity
|
row.order_quantity = order_quantity
|
||||||
row.order_uom = order_uom
|
row.order_uom = order_uom
|
||||||
|
|
||||||
|
if self.batch_handler.allow_item_discounts():
|
||||||
|
row.discount_percent = discount_percent
|
||||||
|
|
||||||
# nb. this will refresh the row
|
# nb. this will refresh the row
|
||||||
pending_info = dict(data['pending_product'])
|
pending_info = dict(data['pending_product'])
|
||||||
self.batch_handler.update_pending_product(row, pending_info)
|
self.batch_handler.update_pending_product(row, pending_info)
|
||||||
|
@ -965,6 +983,9 @@ class CustomerOrderView(MasterView):
|
||||||
{'section': 'rattail.custorders',
|
{'section': 'rattail.custorders',
|
||||||
'option': 'allow_unknown_product',
|
'option': 'allow_unknown_product',
|
||||||
'type': bool},
|
'type': bool},
|
||||||
|
{'section': 'rattail.custorders',
|
||||||
|
'option': 'allow_item_discounts',
|
||||||
|
'type': bool},
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
Loading…
Reference in a new issue