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