mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 17:37:31 -04:00 
			
		
		
		
	Fix invoice item drag/drop sorting
This commit is contained in:
		
							parent
							
								
									b8138288d5
								
							
						
					
					
						commit
						cb09c9d5ae
					
				| @ -858,19 +858,14 @@ | ||||
|             @endif | ||||
| 
 | ||||
|             @if (isset($tasks) && $tasks) | ||||
|                 // move the blank invoice line item to the end
 | ||||
|                 var blank = model.invoice().invoice_items.pop(); | ||||
|                 var tasks = {!! json_encode($tasks) !!}; | ||||
| 
 | ||||
|                 for (var i=0; i<tasks.length; i++) { | ||||
|                     var task = tasks[i]; | ||||
|                     var item = model.invoice().addItem(); | ||||
|                     var item = model.invoice().addItem(true); | ||||
|                     item.notes(task.description); | ||||
|                     item.qty(task.duration); | ||||
|                     item.task_public_id(task.publicId); | ||||
|                     item.invoice_item_type_id({{ INVOICE_ITEM_TYPE_TASK }}); | ||||
|                 } | ||||
|                 model.invoice().invoice_items.push(blank); | ||||
|                 model.invoice().has_tasks(true); | ||||
|             @endif | ||||
| 
 | ||||
| @ -878,7 +873,7 @@ | ||||
|                 model.expense_currency_id({{ isset($expenseCurrencyId) ? $expenseCurrencyId : 0 }}); | ||||
| 
 | ||||
|                 // move the blank invoice line item to the end
 | ||||
|                 var blank = model.invoice().invoice_items.pop(); | ||||
|                 var blank = model.invoice().invoice_items_without_tasks.pop(); | ||||
|                 var expenses = {!! $expenses !!} | ||||
| 
 | ||||
|                 for (var i=0; i<expenses.length; i++) { | ||||
| @ -894,7 +889,7 @@ | ||||
|                     item.tax_rate2(expense.tax_rate2); | ||||
|                     item.tax_name2(expense.tax_name2); | ||||
|                 } | ||||
|                 model.invoice().invoice_items.push(blank); | ||||
|                 model.invoice().invoice_items_without_tasks.push(blank); | ||||
|                 model.invoice().has_expenses(true); | ||||
|             @endif | ||||
| 
 | ||||
| @ -1552,23 +1547,25 @@ | ||||
| 	{ | ||||
| 		var hasEmptyStandard = false; | ||||
| 		var hasEmptyTask = false; | ||||
| 		for(var i=0; i<model.invoice().invoice_items().length; i++) { | ||||
| 			var item = model.invoice().invoice_items()[i]; | ||||
| 
 | ||||
| 		for (var i=0; i<model.invoice().invoice_items_without_tasks().length; i++) { | ||||
| 			var item = model.invoice().invoice_items_without_tasks()[i]; | ||||
| 			if (item.isEmpty()) { | ||||
| 				if (item.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }}) { | ||||
| 					hasEmptyTask = true; | ||||
| 				} else { | ||||
| 					hasEmptyStandard = true; | ||||
| 				} | ||||
| 				hasEmptyStandard = true; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (!hasEmptyStandard) { | ||||
| 			model.invoice().addItem(); | ||||
| 		} | ||||
| 
 | ||||
| 		for (var i=0; i<model.invoice().invoice_items_with_tasks().length; i++) { | ||||
| 			var item = model.invoice().invoice_items_with_tasks()[i]; | ||||
| 			if (item.isEmpty()) { | ||||
| 				hasEmptyTask = true; | ||||
| 			} | ||||
| 		} | ||||
| 		if (!hasEmptyTask) { | ||||
| 			item = model.invoice().addItem(); | ||||
| 			item.invoice_item_type_id({{ INVOICE_ITEM_TYPE_TASK }}); | ||||
| 			model.invoice().addItem(true); | ||||
| 		} | ||||
| 
 | ||||
| 		if (!silent) { | ||||
|  | ||||
| @ -19,12 +19,12 @@ | ||||
|         <th style="min-width:32px;" class="hide-border"></th> | ||||
|     </tr> | ||||
| </thead> | ||||
| <tbody data-bind="sortable: { data: {{ $isTasks ? 'invoice_items_with_tasks' : 'invoice_items_without_tasks' }}, afterMove: onDragged} {{ $isTasks ? ', visible: $root.hasTasks' : '' }}" | ||||
| <tbody data-bind="sortable: { data: invoice_items_{{ $isTasks ? 'with_tasks' : 'without_tasks' }}, allowDrop: false, afterMove: onDragged} {{ $isTasks ? ', visible: $root.hasTasks' : '' }}" | ||||
|     {!! $isTasks ? 'style="display:none;border-spacing: 100px"' : '' !!}> | ||||
|     <tr data-bind="event: { mouseover: showActions, mouseout: hideActions }" class="sortable-row"> | ||||
|         <td class="hide-border td-icon"> | ||||
|             <i style="display:none" data-bind="visible: actionsVisible() &&
 | ||||
|                 $parent.invoice_items().length > 1" class="fa fa-sort"></i>
 | ||||
|                 $parent.invoice_items_{{ $isTasks ? 'with_tasks' : 'without_tasks' }}().length > 1" class="fa fa-sort"></i>
 | ||||
|         </td> | ||||
|         <td> | ||||
|             <div id="scrollable-dropdown-menu"> | ||||
|  | ||||
| @ -166,15 +166,15 @@ function ViewModel(data) { | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     self.hasTasksCached; | ||||
|     self.hasTasksCached = false; | ||||
|     self.hasTasks = ko.computed(function() { | ||||
|         if (self.hasTasksCached) { | ||||
|             return true; | ||||
|         } | ||||
|         invoice = self.invoice(); | ||||
|         for (var i=0; i<invoice.invoice_items().length; ++i) { | ||||
|         for (var i=0; i<invoice.invoice_items_with_tasks().length; ++i) { | ||||
|             var item = invoice.invoice_items()[i]; | ||||
|             if (! item.isEmpty() && item.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }}) { | ||||
|             if (! item.isEmpty()) { | ||||
|                 self.hasTasksCached = true; | ||||
|                 return true; | ||||
|             } | ||||
| @ -229,7 +229,6 @@ function InvoiceModel(data) { | ||||
|     self.auto_bill = ko.observable(0); | ||||
|     self.client_enable_auto_bill = ko.observable(false); | ||||
|     self.invoice_status_id = ko.observable(0); | ||||
|     self.invoice_items = ko.observableArray(); | ||||
|     self.documents = ko.observableArray(); | ||||
|     self.expenses = ko.observableArray(); | ||||
|     self.amount = ko.observable(0); | ||||
| @ -246,17 +245,33 @@ function InvoiceModel(data) { | ||||
|     self.custom_text_value1 = ko.observable(); | ||||
|     self.custom_text_value2 = ko.observable(); | ||||
| 
 | ||||
|     self.invoice_items_with_tasks = ko.observableArray(); | ||||
|     self.invoice_items_without_tasks = ko.observableArray(); | ||||
|     self.invoice_items = ko.computed({ | ||||
|         read: function () { | ||||
|             return self.invoice_items_with_tasks().concat(self.invoice_items_without_tasks()); | ||||
|         }, | ||||
|         write: function(data) { | ||||
|             self.invoice_items_with_tasks.removeAll(); | ||||
|             self.invoice_items_without_tasks.removeAll(); | ||||
|             for (var i=0; i<data.length; i++) { | ||||
|                 var item = new ItemModel(data[i]); | ||||
|                 if (item.isTask()) { | ||||
|                     self.invoice_items_with_tasks.push(item); | ||||
|                 } else { | ||||
|                     self.invoice_items_without_tasks.push(item); | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         owner: this | ||||
|     }) | ||||
| 
 | ||||
|     self.mapping = { | ||||
|         'client': { | ||||
|             create: function(options) { | ||||
|                 return new ClientModel(options.data); | ||||
|             } | ||||
|         }, | ||||
|         'invoice_items': { | ||||
|             create: function(options) { | ||||
|                 return new ItemModel(options.data); | ||||
|             } | ||||
|         }, | ||||
|         'documents': { | ||||
|             create: function(options) { | ||||
|                 return new DocumentModel(options.data); | ||||
| @ -269,7 +284,7 @@ function InvoiceModel(data) { | ||||
|         }, | ||||
|     } | ||||
| 
 | ||||
|     self.addItem = function() { | ||||
|     self.addItem = function(isTask) { | ||||
|         if (self.invoice_items().length >= {{ MAX_INVOICE_ITEMS }}) { | ||||
|             return false; | ||||
|         } | ||||
| @ -277,7 +292,12 @@ function InvoiceModel(data) { | ||||
|         @if ($account->hide_quantity) | ||||
|             itemModel.qty(1); | ||||
|         @endif | ||||
|         self.invoice_items.push(itemModel); | ||||
|         if (isTask) { | ||||
|             itemModel.invoice_item_type_id({{ INVOICE_ITEM_TYPE_TASK }}); | ||||
|             self.invoice_items_with_tasks.push(itemModel); | ||||
|         } else { | ||||
|             self.invoice_items_without_tasks.push(itemModel); | ||||
|         } | ||||
|         applyComboboxListeners(); | ||||
|         return itemModel; | ||||
|     } | ||||
| @ -329,7 +349,11 @@ function InvoiceModel(data) { | ||||
|     }) | ||||
| 
 | ||||
|     self.removeItem = function(item) { | ||||
|         self.invoice_items.remove(item); | ||||
|         if (item.isTask()) { | ||||
|             self.invoice_items_with_tasks.remove(item); | ||||
|         } else { | ||||
|             self.invoice_items_without_tasks.remove(item); | ||||
|         } | ||||
|         refreshPDF(true); | ||||
|     } | ||||
| 
 | ||||
| @ -568,18 +592,6 @@ function InvoiceModel(data) { | ||||
|         } | ||||
|         self.applyInclusivTax(taxRate); | ||||
|     } | ||||
| 
 | ||||
|     self.invoice_items_with_tasks = ko.computed(function() { | ||||
|         return ko.utils.arrayFilter(self.invoice_items(), function(item) { | ||||
|             return item.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }}; | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|     self.invoice_items_without_tasks = ko.computed(function() { | ||||
|         return ko.utils.arrayFilter(self.invoice_items(), function(item) { | ||||
|             return item.invoice_item_type_id() != {{ INVOICE_ITEM_TYPE_TASK }}; | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| function ClientModel(data) { | ||||
| @ -769,6 +781,10 @@ function ItemModel(data) { | ||||
|     self.invoice_item_type_id = ko.observable({{ INVOICE_ITEM_TYPE_STANDARD }}); | ||||
|     self.actionsVisible = ko.observable(false); | ||||
| 
 | ||||
|     self.isTask = ko.computed(function() { | ||||
|         return self.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }}; | ||||
|     }); | ||||
| 
 | ||||
|     this.tax1 = ko.computed({ | ||||
|         read: function () { | ||||
|             return self.tax_rate1IsInclusive() + ' ' + self.tax_rate1() + ' ' + self.tax_name1(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user