feat: add per-department default item discount
This commit is contained in:
parent
7e1d68e2cf
commit
aa31d23fc8
|
@ -234,7 +234,10 @@
|
|||
<b-field horizontal label="Sold by Weight">
|
||||
<span>${app.render_boolean(item.product_weighed)}</span>
|
||||
</b-field>
|
||||
<b-field horizontal label="Department">
|
||||
<b-field horizontal label="Department ID">
|
||||
<span>${item.department_id}</span>
|
||||
</b-field>
|
||||
<b-field horizontal label="Department Name">
|
||||
<span>${item.department_name}</span>
|
||||
</b-field>
|
||||
<b-field horizontal label="Special Order">
|
||||
|
|
|
@ -107,15 +107,111 @@
|
|||
</b-field>
|
||||
|
||||
<div v-show="simpleSettings['sideshow.orders.allow_item_discounts']"
|
||||
class="level-left block">
|
||||
<div class="level-item">Default item discount</div>
|
||||
<div class="level-item">
|
||||
<b-input name="sideshow.orders.default_item_discount"
|
||||
v-model="simpleSettings['sideshow.orders.default_item_discount']"
|
||||
@input="settingsNeedSaved = true"
|
||||
style="width: 5rem;" />
|
||||
class="block"
|
||||
style="display: flex; gap: 0.5rem; align-items: center;">
|
||||
<span>Global default item discount</span>
|
||||
<b-input name="sideshow.orders.default_item_discount"
|
||||
v-model="simpleSettings['sideshow.orders.default_item_discount']"
|
||||
@input="settingsNeedSaved = true"
|
||||
style="width: 5rem;" />
|
||||
<span>%</span>
|
||||
</div>
|
||||
|
||||
<div v-show="simpleSettings['sideshow.orders.allow_item_discounts']"
|
||||
style="width: 50%;">
|
||||
<div style="display: flex; gap: 1rem; align-items: center;">
|
||||
<p>Per-Department default item discounts</p>
|
||||
<div>
|
||||
<b-button type="is-primary"
|
||||
@click="deptItemDiscountInit()"
|
||||
icon-pack="fas"
|
||||
icon-left="plus">
|
||||
Add
|
||||
</b-button>
|
||||
<input type="hidden" name="dept_item_discounts" :value="JSON.stringify(deptItemDiscounts)" />
|
||||
<${b}-modal has-modal-card
|
||||
% if request.use_oruga:
|
||||
v-model:active="deptItemDiscountShowDialog"
|
||||
% else:
|
||||
:active.sync="deptItemDiscountShowDialog"
|
||||
% endif
|
||||
>
|
||||
<div class="modal-card">
|
||||
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Default Discount for Department</p>
|
||||
</header>
|
||||
|
||||
<section class="modal-card-body">
|
||||
<div style="display: flex; gap: 1rem;">
|
||||
<b-field label="Dept. ID"
|
||||
:type="deptItemDiscountDeptID ? null : 'is-danger'">
|
||||
<b-input v-model="deptItemDiscountDeptID"
|
||||
ref="deptItemDiscountDeptID"
|
||||
style="width: 6rem;;" />
|
||||
</b-field>
|
||||
<b-field label="Department Name"
|
||||
:type="deptItemDiscountDeptName ? null : 'is-danger'"
|
||||
style="flex-grow: 1;">
|
||||
<b-input v-model="deptItemDiscountDeptName" />
|
||||
</b-field>
|
||||
<b-field label="Discount"
|
||||
:type="deptItemDiscountPercent ? null : 'is-danger'">
|
||||
<div style="display: flex; gap: 0.5rem; align-items: center;">
|
||||
<b-input v-model="deptItemDiscountPercent"
|
||||
ref="deptItemDiscountPercent"
|
||||
style="width: 6rem;" />
|
||||
<span>%</span>
|
||||
</div>
|
||||
</b-field>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="modal-card-foot">
|
||||
<b-button type="is-primary"
|
||||
icon-pack="fas"
|
||||
icon-left="save"
|
||||
:disabled="deptItemDiscountSaveDisabled"
|
||||
@click="deptItemDiscountSave()">
|
||||
Save
|
||||
</b-button>
|
||||
<b-button @click="deptItemDiscountShowDialog = false">
|
||||
Cancel
|
||||
</b-button>
|
||||
</footer>
|
||||
</div>
|
||||
</${b}-modal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-item">%</div>
|
||||
<${b}-table :data="deptItemDiscounts">
|
||||
<${b}-table-column field="department_id"
|
||||
label="Dept. ID"
|
||||
v-slot="props">
|
||||
{{ props.row.department_id }}
|
||||
</${b}-table-column>
|
||||
<${b}-table-column field="department_name"
|
||||
label="Department Name"
|
||||
v-slot="props">
|
||||
{{ props.row.department_name }}
|
||||
</${b}-table-column>
|
||||
<${b}-table-column field="default_item_discount"
|
||||
label="Discount"
|
||||
v-slot="props">
|
||||
{{ props.row.default_item_discount }} %
|
||||
</${b}-table-column>
|
||||
<${b}-table-column label="Actions"
|
||||
v-slot="props">
|
||||
<a href="#" @click.prevent="deptItemDiscountInit(props.row)">
|
||||
<i class="fas fa-edit" />
|
||||
Edit
|
||||
</a>
|
||||
<a href="#" @click.prevent="deptItemDiscountDelete(props.row)"
|
||||
class="has-text-danger">
|
||||
<i class="fas fa-trash" />
|
||||
Delete
|
||||
</a>
|
||||
</${b}-table-column>
|
||||
</${b}-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -145,5 +241,62 @@
|
|||
|
||||
ThisPageData.batchHandlers = ${json.dumps(batch_handlers)|n}
|
||||
|
||||
ThisPageData.deptItemDiscounts = ${json.dumps(dept_item_discounts)|n}
|
||||
ThisPageData.deptItemDiscountShowDialog = false
|
||||
ThisPageData.deptItemDiscountRow = null
|
||||
ThisPageData.deptItemDiscountDeptID = null
|
||||
ThisPageData.deptItemDiscountDeptName = null
|
||||
ThisPageData.deptItemDiscountPercent = null
|
||||
|
||||
ThisPage.computed.deptItemDiscountSaveDisabled = function() {
|
||||
if (!this.deptItemDiscountDeptID) {
|
||||
return true
|
||||
}
|
||||
if (!this.deptItemDiscountDeptName) {
|
||||
return true
|
||||
}
|
||||
if (!this.deptItemDiscountPercent) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
ThisPage.methods.deptItemDiscountDelete = function(row) {
|
||||
const i = this.deptItemDiscounts.indexOf(row)
|
||||
this.deptItemDiscounts.splice(i, 1)
|
||||
this.settingsNeedSaved = true
|
||||
}
|
||||
|
||||
ThisPage.methods.deptItemDiscountInit = function(row) {
|
||||
this.deptItemDiscountRow = row
|
||||
this.deptItemDiscountDeptID = row?.department_id
|
||||
this.deptItemDiscountDeptName = row?.department_name
|
||||
this.deptItemDiscountPercent = row?.default_item_discount
|
||||
this.deptItemDiscountShowDialog = true
|
||||
this.$nextTick(() => {
|
||||
if (row) {
|
||||
this.$refs.deptItemDiscountPercent.focus()
|
||||
} else {
|
||||
this.$refs.deptItemDiscountDeptID.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ThisPage.methods.deptItemDiscountSave = function() {
|
||||
if (this.deptItemDiscountRow) {
|
||||
this.deptItemDiscountRow.department_id = this.deptItemDiscountDeptID
|
||||
this.deptItemDiscountRow.department_name = this.deptItemDiscountDeptName
|
||||
this.deptItemDiscountRow.default_item_discount = this.deptItemDiscountPercent
|
||||
} else {
|
||||
this.deptItemDiscounts.push({
|
||||
department_id: this.deptItemDiscountDeptID,
|
||||
department_name: this.deptItemDiscountDeptName,
|
||||
default_item_discount: this.deptItemDiscountPercent,
|
||||
})
|
||||
}
|
||||
this.deptItemDiscountShowDialog = false
|
||||
this.settingsNeedSaved = true
|
||||
}
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
|
|
@ -504,7 +504,16 @@
|
|||
<b-input v-model="pendingProduct.scancode" />
|
||||
</b-field>
|
||||
|
||||
<b-field label="Department"
|
||||
<b-field label="Dept. ID"
|
||||
% if 'department_id' in pending_product_required_fields:
|
||||
:type="pendingProduct.department_id ? null : 'is-danger'"
|
||||
% endif
|
||||
style="width: 15rem;">
|
||||
<b-input v-model="pendingProduct.department_id"
|
||||
@input="updateDiscount" />
|
||||
</b-field>
|
||||
|
||||
<b-field label="Department Name"
|
||||
% if 'department_name' in pending_product_required_fields:
|
||||
:type="pendingProduct.department_name ? null : 'is-danger'"
|
||||
% endif
|
||||
|
@ -512,8 +521,7 @@
|
|||
<b-input v-model="pendingProduct.department_name" />
|
||||
</b-field>
|
||||
|
||||
<b-field label="Special Order"
|
||||
style="width: 100%;">
|
||||
<b-field label="Special Order">
|
||||
<b-checkbox v-model="pendingProduct.special_order" />
|
||||
</b-field>
|
||||
|
||||
|
@ -750,7 +758,7 @@
|
|||
|
||||
<${b}-table-column label="Department"
|
||||
v-slot="props">
|
||||
{{ props.row.department_display }}
|
||||
{{ props.row.department_name }}
|
||||
</${b}-table-column>
|
||||
|
||||
<${b}-table-column label="Quantity"
|
||||
|
@ -922,8 +930,10 @@
|
|||
productCaseSize: null,
|
||||
|
||||
% if allow_item_discounts:
|
||||
productDiscountPercent: ${json.dumps(default_item_discount)|n},
|
||||
defaultItemDiscount: ${json.dumps(default_item_discount)|n},
|
||||
deptItemDiscounts: ${json.dumps(dept_item_discounts)|n},
|
||||
allowDiscountsIfOnSale: ${json.dumps(allow_item_discounts_if_on_sale)|n},
|
||||
productDiscountPercent: null,
|
||||
% endif
|
||||
|
||||
pendingProduct: {},
|
||||
|
@ -1259,6 +1269,21 @@
|
|||
})
|
||||
},
|
||||
|
||||
% if allow_item_discounts:
|
||||
|
||||
updateDiscount(deptID) {
|
||||
// nb. our map requires ID is string
|
||||
deptID = deptID.toString()
|
||||
const i = Object.keys(this.deptItemDiscounts).indexOf(deptID)
|
||||
if (i == -1) {
|
||||
this.productDiscountPercent = this.defaultItemDiscount
|
||||
} else {
|
||||
this.productDiscountPercent = this.deptItemDiscounts[deptID]
|
||||
}
|
||||
},
|
||||
|
||||
% endif
|
||||
|
||||
editNewCustomerSave() {
|
||||
this.editNewCustomerSaving = true
|
||||
|
||||
|
@ -1397,7 +1422,7 @@
|
|||
this.productUnitChoices = this.defaultUnitChoices
|
||||
|
||||
% if allow_item_discounts:
|
||||
this.productDiscountPercent = ${json.dumps(default_item_discount)|n}
|
||||
this.productDiscountPercent = this.defaultItemDiscount
|
||||
% endif
|
||||
},
|
||||
|
||||
|
@ -1436,7 +1461,15 @@
|
|||
this.productSaleEndsDisplay = data.sale_ends_display
|
||||
|
||||
% if allow_item_discounts:
|
||||
this.productDiscountPercent = this.allowItemDiscount ? data.default_item_discount : null
|
||||
if (this.allowItemDiscount) {
|
||||
if (data?.default_item_discount != null) {
|
||||
this.productDiscountPercent = data.default_item_discount
|
||||
} else {
|
||||
this.updateDiscount(data?.department_id)
|
||||
}
|
||||
} else {
|
||||
this.productDiscountPercent = null
|
||||
}
|
||||
% endif
|
||||
|
||||
// this.setProductUnitChoices(data.uom_choices)
|
||||
|
@ -1514,7 +1547,7 @@
|
|||
this.productUOM = this.defaultUOM
|
||||
|
||||
% if allow_item_discounts:
|
||||
this.productDiscountPercent = ${json.dumps(default_item_discount)|n}
|
||||
this.productDiscountPercent = this.defaultItemDiscount
|
||||
% endif
|
||||
|
||||
% if request.use_oruga:
|
||||
|
@ -1615,7 +1648,7 @@
|
|||
this.editItemLoading = true
|
||||
|
||||
const params = {
|
||||
order_qty: this.productQuantity,
|
||||
order_qty: parseFloat(this.productQuantity),
|
||||
order_uom: this.productUOM,
|
||||
}
|
||||
|
||||
|
@ -1626,7 +1659,9 @@
|
|||
}
|
||||
|
||||
% if allow_item_discounts:
|
||||
params.discount_percent = this.productDiscountPercent
|
||||
if (this.productDiscountPercent) {
|
||||
params.discount_percent = parseFloat(this.productDiscountPercent)
|
||||
}
|
||||
% endif
|
||||
|
||||
if (this.editItemRow) {
|
||||
|
|
|
@ -25,7 +25,9 @@ Views for Orders
|
|||
"""
|
||||
|
||||
import decimal
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
import colander
|
||||
import sqlalchemy as sa
|
||||
|
@ -144,6 +146,7 @@ class OrderView(MasterView):
|
|||
'brand_name',
|
||||
'description',
|
||||
'size',
|
||||
'department_id',
|
||||
'department_name',
|
||||
'vendor_name',
|
||||
'vendor_item_code',
|
||||
|
@ -304,6 +307,8 @@ class OrderView(MasterView):
|
|||
# nb. render quantity so that '10.0' => '10'
|
||||
context['default_item_discount'] = self.app.render_quantity(
|
||||
self.batch_handler.get_default_item_discount())
|
||||
context['dept_item_discounts'] = dict([(d['department_id'], d['default_item_discount'])
|
||||
for d in self.get_dept_item_discounts()])
|
||||
|
||||
return self.render_to_response('create', context)
|
||||
|
||||
|
@ -401,6 +406,43 @@ class OrderView(MasterView):
|
|||
required.append(field)
|
||||
return required
|
||||
|
||||
def get_dept_item_discounts(self):
|
||||
"""
|
||||
Returns the list of per-department default item discount settings.
|
||||
|
||||
Each entry in the list will look like::
|
||||
|
||||
{
|
||||
'department_id': '42',
|
||||
'department_name': 'Grocery',
|
||||
'default_item_discount': 10,
|
||||
}
|
||||
|
||||
:returns: List of department settings as shown above.
|
||||
"""
|
||||
model = self.app.model
|
||||
session = self.Session()
|
||||
pattern = re.compile(r'^sideshow\.orders\.departments\.([^.]+)\.default_item_discount$')
|
||||
|
||||
dept_item_discounts = []
|
||||
settings = session.query(model.Setting)\
|
||||
.filter(model.Setting.name.like('sideshow.orders.departments.%.default_item_discount'))\
|
||||
.all()
|
||||
for setting in settings:
|
||||
match = pattern.match(setting.name)
|
||||
if not match:
|
||||
log.warning("invalid setting name: %s", setting.name)
|
||||
continue
|
||||
deptid = match.group(1)
|
||||
name = self.app.get_setting(session, f'sideshow.orders.departments.{deptid}.name')
|
||||
dept_item_discounts.append({
|
||||
'department_id': deptid,
|
||||
'department_name': name,
|
||||
'default_item_discount': setting.value,
|
||||
})
|
||||
dept_item_discounts.sort(key=lambda d: d['department_name'])
|
||||
return dept_item_discounts
|
||||
|
||||
def start_over(self, batch):
|
||||
"""
|
||||
This will delete the user's current batch, then redirect user
|
||||
|
@ -598,9 +640,6 @@ class OrderView(MasterView):
|
|||
if 'case_price_quoted' in data and 'case_price_quoted_display' not in data:
|
||||
data['case_price_quoted_display'] = self.app.render_currency(data['case_price_quoted'])
|
||||
|
||||
if 'default_item_discount' not in data:
|
||||
data['default_item_discount'] = self.batch_handler.get_default_item_discount()
|
||||
|
||||
decimal_fields = [
|
||||
'case_size',
|
||||
'unit_price_reg',
|
||||
|
@ -753,7 +792,8 @@ class OrderView(MasterView):
|
|||
row.product_description,
|
||||
row.product_size),
|
||||
'product_weighed': row.product_weighed,
|
||||
'department_display': row.department_name,
|
||||
'department_id': row.department_id,
|
||||
'department_name': row.department_name,
|
||||
'special_order': row.special_order,
|
||||
'case_size': float(row.case_size) if row.case_size is not None else None,
|
||||
'order_qty': float(row.order_qty),
|
||||
|
@ -990,8 +1030,39 @@ class OrderView(MasterView):
|
|||
handlers = [{'spec': spec} for spec in handlers]
|
||||
context['batch_handlers'] = handlers
|
||||
|
||||
context['dept_item_discounts'] = self.get_dept_item_discounts()
|
||||
|
||||
return context
|
||||
|
||||
def configure_gather_settings(self, data, simple_settings=None):
|
||||
""" """
|
||||
settings = super().configure_gather_settings(data, simple_settings=simple_settings)
|
||||
|
||||
for dept in json.loads(data['dept_item_discounts']):
|
||||
deptid = dept['department_id']
|
||||
settings.append({'name': f'sideshow.orders.departments.{deptid}.name',
|
||||
'value': dept['department_name']})
|
||||
settings.append({'name': f'sideshow.orders.departments.{deptid}.default_item_discount',
|
||||
'value': dept['default_item_discount']})
|
||||
|
||||
return settings
|
||||
|
||||
def configure_remove_settings(self, **kwargs):
|
||||
""" """
|
||||
model = self.app.model
|
||||
session = self.Session()
|
||||
|
||||
super().configure_remove_settings(**kwargs)
|
||||
|
||||
to_delete = session.query(model.Setting)\
|
||||
.filter(sa.or_(
|
||||
model.Setting.name.like('sideshow.orders.departments.%.name'),
|
||||
model.Setting.name.like('sideshow.orders.departments.%.default_item_discount')))\
|
||||
.all()
|
||||
for setting in to_delete:
|
||||
self.app.delete_setting(session, setting.name)
|
||||
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
cls._order_defaults(config)
|
||||
|
|
|
@ -235,6 +235,7 @@ class PendingProductView(MasterView):
|
|||
url_prefix = '/pending/products'
|
||||
|
||||
labels = {
|
||||
'department_id': "Department ID",
|
||||
'product_id': "Product ID",
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import datetime
|
||||
import decimal
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from sqlalchemy import orm
|
||||
|
@ -291,6 +292,50 @@ class TestOrderView(WebTestCase):
|
|||
fields = view.get_pending_product_required_fields()
|
||||
self.assertEqual(fields, ['brand_name', 'size', 'unit_price_reg'])
|
||||
|
||||
def test_get_dept_item_discounts(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
|
||||
# empty list by default
|
||||
discounts = view.get_dept_item_discounts()
|
||||
self.assertEqual(discounts, [])
|
||||
|
||||
# mock settings
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.5.name', 'Bulk')
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.5.default_item_discount', '15')
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.6.name', 'Produce')
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.6.default_item_discount', '5')
|
||||
discounts = view.get_dept_item_discounts()
|
||||
self.assertEqual(len(discounts), 2)
|
||||
self.assertEqual(discounts[0], {
|
||||
'department_id': '5',
|
||||
'department_name': 'Bulk',
|
||||
'default_item_discount': '15',
|
||||
})
|
||||
self.assertEqual(discounts[1], {
|
||||
'department_id': '6',
|
||||
'department_name': 'Produce',
|
||||
'default_item_discount': '5',
|
||||
})
|
||||
|
||||
# invalid setting
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.I.N.V.A.L.I.D.name', 'Bad News')
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.I.N.V.A.L.I.D.default_item_discount', '42')
|
||||
discounts = view.get_dept_item_discounts()
|
||||
self.assertEqual(len(discounts), 2)
|
||||
self.assertEqual(discounts[0], {
|
||||
'department_id': '5',
|
||||
'department_name': 'Bulk',
|
||||
'default_item_discount': '15',
|
||||
})
|
||||
self.assertEqual(discounts[1], {
|
||||
'department_id': '6',
|
||||
'department_name': 'Produce',
|
||||
'default_item_discount': '5',
|
||||
})
|
||||
|
||||
def test_get_context_customer(self):
|
||||
self.pyramid_config.add_route('orders', '/orders/')
|
||||
model = self.app.model
|
||||
|
@ -1288,6 +1333,12 @@ class TestOrderView(WebTestCase):
|
|||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.5.name', 'Bulk')
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.5.default_item_discount', '15')
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.6.name', 'Produce')
|
||||
self.app.save_setting(self.session, 'sideshow.orders.departments.6.default_item_discount', '5')
|
||||
self.session.commit()
|
||||
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
with patch.multiple(self.config, usedb=True, preferdb=True):
|
||||
|
||||
|
@ -1295,7 +1346,19 @@ class TestOrderView(WebTestCase):
|
|||
allowed = self.config.get_bool('sideshow.orders.allow_unknown_products',
|
||||
session=self.session)
|
||||
self.assertIsNone(allowed)
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 0)
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 4)
|
||||
discounts = view.get_dept_item_discounts()
|
||||
self.assertEqual(len(discounts), 2)
|
||||
self.assertEqual(discounts[0], {
|
||||
'department_id': '5',
|
||||
'department_name': 'Bulk',
|
||||
'default_item_discount': '15',
|
||||
})
|
||||
self.assertEqual(discounts[1], {
|
||||
'department_id': '6',
|
||||
'department_name': 'Produce',
|
||||
'default_item_discount': '5',
|
||||
})
|
||||
|
||||
# fetch initial page
|
||||
response = view.configure()
|
||||
|
@ -1305,13 +1368,18 @@ class TestOrderView(WebTestCase):
|
|||
allowed = self.config.get_bool('sideshow.orders.allow_unknown_products',
|
||||
session=self.session)
|
||||
self.assertIsNone(allowed)
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 0)
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 4)
|
||||
|
||||
# post new settings
|
||||
with patch.multiple(self.request, create=True,
|
||||
method='POST',
|
||||
POST={
|
||||
'sideshow.orders.allow_unknown_products': 'true',
|
||||
'dept_item_discounts': json.dumps([{
|
||||
'department_id': '5',
|
||||
'department_name': 'Grocery',
|
||||
'default_item_discount': 10,
|
||||
}])
|
||||
}):
|
||||
response = view.configure()
|
||||
self.assertIsInstance(response, HTTPFound)
|
||||
|
@ -1320,6 +1388,13 @@ class TestOrderView(WebTestCase):
|
|||
session=self.session)
|
||||
self.assertTrue(allowed)
|
||||
self.assertTrue(self.session.query(model.Setting).count() > 1)
|
||||
discounts = view.get_dept_item_discounts()
|
||||
self.assertEqual(len(discounts), 1)
|
||||
self.assertEqual(discounts[0], {
|
||||
'department_id': '5',
|
||||
'department_name': 'Grocery',
|
||||
'default_item_discount': '10',
|
||||
})
|
||||
|
||||
|
||||
class OrderItemViewTestMixin:
|
||||
|
|
Loading…
Reference in a new issue