mirror of
				https://github.com/itsdave-de/msp.git
				synced 2025-10-30 17:07:09 -03:00 
			
		
		
		
	Auto invoice generator: Allow creation of invoices, though we have drafts for a customer, skip positions from drafts.
This commit is contained in:
		
							parent
							
								
									4653083a5d
								
							
						
					
					
						commit
						1909ff6ed9
					
				| @ -12,6 +12,7 @@ | |||||||
|   "invoices_from_delivery_notes_section", |   "invoices_from_delivery_notes_section", | ||||||
|   "customer", |   "customer", | ||||||
|   "get_invoice", |   "get_invoice", | ||||||
|  |   "inv_without_draft", | ||||||
|   "it_contract_invoices_section", |   "it_contract_invoices_section", | ||||||
|   "billing_month", |   "billing_month", | ||||||
|   "contract_invoices", |   "contract_invoices", | ||||||
| @ -48,7 +49,7 @@ | |||||||
|    "fieldname": "get_invoice", |    "fieldname": "get_invoice", | ||||||
|    "fieldtype": "Button", |    "fieldtype": "Button", | ||||||
|    "label": "Get Invoice", |    "label": "Get Invoice", | ||||||
|    "options": "get_invoice_dict" |    "options": "generate_invoices" | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|    "fieldname": "date", |    "fieldname": "date", | ||||||
| @ -93,15 +94,22 @@ | |||||||
|    "fieldname": "it_contract_invoices_section", |    "fieldname": "it_contract_invoices_section", | ||||||
|    "fieldtype": "Section Break", |    "fieldtype": "Section Break", | ||||||
|    "label": "IT Contract Invoices" |    "label": "IT Contract Invoices" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "description": "Rechnungserstellung f\u00fcr Kunden, f\u00fcr die rechnungen im Entwurfstatus existeren", | ||||||
|  |    "fieldname": "inv_without_draft", | ||||||
|  |    "fieldtype": "Button", | ||||||
|  |    "label": "Invoice without draft article ", | ||||||
|  |    "options": "generate_invoices_without_draft_items" | ||||||
|   } |   } | ||||||
|  ], |  ], | ||||||
|  "index_web_pages_for_search": 1, |  "index_web_pages_for_search": 1, | ||||||
|  "links": [], |  "links": [], | ||||||
|  "migration_hash": "d64bd35ec0b0d442bcfc080be217f2f6", |  "modified": "2024-07-31 11:37:09.454442", | ||||||
|  "modified": "2023-05-31 11:12:52.773165", |  | ||||||
|  "modified_by": "Administrator", |  "modified_by": "Administrator", | ||||||
|  "module": "MSP", |  "module": "MSP", | ||||||
|  "name": "Auto Invoice Generator", |  "name": "Auto Invoice Generator", | ||||||
|  |  "naming_rule": "Expression (old style)", | ||||||
|  "owner": "Administrator", |  "owner": "Administrator", | ||||||
|  "permissions": [ |  "permissions": [ | ||||||
|   { |   { | ||||||
| @ -119,5 +127,6 @@ | |||||||
|  ], |  ], | ||||||
|  "sort_field": "modified", |  "sort_field": "modified", | ||||||
|  "sort_order": "DESC", |  "sort_order": "DESC", | ||||||
|  |  "states": [], | ||||||
|  "track_changes": 1 |  "track_changes": 1 | ||||||
| } | } | ||||||
| @ -86,7 +86,7 @@ class AutoInvoiceGenerator(Document): | |||||||
| 
 | 
 | ||||||
| 		return cust_del_note  | 		return cust_del_note  | ||||||
| 
 | 
 | ||||||
| 	def get_invoicing_items_for_cust(self,cust): | 	def get_invoicing_items_for_customer(self,cust): | ||||||
| 		#Funktion liefert eine Liste aller abrechenbaren Items für den jeweiligen Kunden | 		#Funktion liefert eine Liste aller abrechenbaren Items für den jeweiligen Kunden | ||||||
| 		 | 		 | ||||||
| 		del_not = self.get_delivery_notes_for_invoicing() | 		del_not = self.get_delivery_notes_for_invoicing() | ||||||
| @ -114,154 +114,341 @@ class AutoInvoiceGenerator(Document): | |||||||
| 	 | 	 | ||||||
| 	 | 	 | ||||||
| 	 | 	 | ||||||
|  | 	#@frappe.whitelist() | ||||||
|  | 	# def get_invoice_dict(self):  | ||||||
|  | 	# 	self.get_customer_asap_billing_mode() | ||||||
|  | 	# 	del_not = self.get_delivery_notes_for_invoicing() | ||||||
|  | 	# 	cust_list = self.get_customer_for_invoicing(del_not) | ||||||
|  | 	# 	if self.customer:  | ||||||
|  | 	# 		customer_list = [self.customer] | ||||||
|  | 	# 	else: | ||||||
|  | 	# 		customer_list = cust_list | ||||||
|  | 
 | ||||||
|  | 	# 	print(len(customer_list)) | ||||||
|  | 	# 	cust_count = 0 | ||||||
|  | 	# 	invoice_count = 0 | ||||||
|  | 	# 	log_list = [] | ||||||
|  | 	# 	for cust in customer_list: | ||||||
|  | 	# 		cust_doc = frappe.get_doc("Customer",cust) | ||||||
|  | 	# 		invoice_in_draft = frappe.get_all("Sales Invoice", filters = {"status" : "Draft", "customer": cust}) | ||||||
|  | 	# 		if len(invoice_in_draft) > 0: | ||||||
|  | 	# 			log_list.append("Für Kunde"+ " "+ cust + " wurden keine Rechnungen erstellt, da noch nicht berechnete Rechnungen in Draft vorhanden")  | ||||||
|  | 	# 			continue | ||||||
|  | 	# 		else: | ||||||
|  | 	# 			cust_count += 1 | ||||||
|  | 	# 			items = self.get_invoicing_items_for_cust(cust) | ||||||
|  | 	# 			print(items) | ||||||
|  | 	# 			print("len Items") | ||||||
|  | 	# 			print(len(items)) | ||||||
|  | 	# 			invoicing_items = [] | ||||||
|  | 
 | ||||||
|  | 	# 			if cust_doc.billing_mode == "ASAP": | ||||||
|  | 	# 				x = self.get_delivery_notes_for_customer(cust, del_not) | ||||||
|  | 	# 				for dn in x: | ||||||
|  | 	# 					item_doc = frappe.get_doc("Delivery Note", dn["name"])  | ||||||
|  | 	# 					items = [self.create_invoice_doc_item(item) for item in item_doc.items] | ||||||
|  | 	# 					for item in items: | ||||||
|  | 	# 						item.delivery_note= dn["name"] | ||||||
|  | 
 | ||||||
|  | 	# 					if len(items) > 0: | ||||||
|  | 	# 						self.create_invoice(cust, items, "Abrechnung Lieferschein " + dn["name"]+ " " + cust_doc.customer_name) | ||||||
|  | 	# 						invoice_count += 1 | ||||||
|  | 	# 			elif cust_doc.billing_mode == "Collective Bill": | ||||||
|  | 	# 				for item in items: | ||||||
|  | 	# 					invoice_doc_item = self.create_invoice_doc_item(item) | ||||||
|  | 	# 					invoicing_items.append(invoice_doc_item) | ||||||
|  | 	# 				if len(invoicing_items) > 0: | ||||||
|  | 	# 					self.create_invoice(cust, invoicing_items, "Sammelrechnung " + cust_doc.customer_name) | ||||||
|  | 	# 					invoice_count += 1 | ||||||
|  | 	# 			else:	 | ||||||
|  | 	# 				item_group_separation_dict = get_item_group_assignment_table(cust) | ||||||
|  | 	# 				print(item_group_separation_dict) | ||||||
|  | 					 | ||||||
|  | 	# 				separation_item_groups = [[item_group_separation_dict[x].item_group,item_group_separation_dict[x].filter]  for x in range(1, len(item_group_separation_dict) + 1) ]	 | ||||||
|  | 	# 				if cust_doc.billing_mode == "per Item Group": | ||||||
|  | 	# 					print("vor Separation") | ||||||
|  | 	# 					print(len(items)) | ||||||
|  | 	# 					for el in separation_item_groups: | ||||||
|  | 	# 						print(el[1]) | ||||||
|  | 	# 						print(items) | ||||||
|  | 	# 						a = [] | ||||||
|  | 	# 						items_list = items.copy() | ||||||
|  | 	# 						for item in items_list: | ||||||
|  | 	# 						# for i in item_name: | ||||||
|  | 	# 						# 	item = filter(lambda item: item['name'] == i, items) | ||||||
|  | 	# 							print(item) | ||||||
|  | 
 | ||||||
|  | 	# 							#print(item.item_group) | ||||||
|  | 	# 							if item.item_group in el[1]: | ||||||
|  | 	# 								print(True) | ||||||
|  | 	# 								invoice_doc_item = self.create_invoice_doc_item(item) | ||||||
|  | 	# 								print(invoice_doc_item) | ||||||
|  | 	# 								a.append(invoice_doc_item) | ||||||
|  | 	# 								items.remove(item) | ||||||
|  | 	# 								print(len(a)) | ||||||
|  | 	# 								print(len(items)) | ||||||
|  | 									 | ||||||
|  | 	# 							else: | ||||||
|  | 	# 								print(False) | ||||||
|  | 	# 						if len(a) > 0: | ||||||
|  | 	# 							self.create_invoice(cust, a, el[0] + " " +cust_doc.customer_name) | ||||||
|  | 	# 							invoice_count +=1 | ||||||
|  | 	# 						print("nach Separation") | ||||||
|  | 	# 						print(len(items))	 | ||||||
|  | 	# 					i_items = [self.create_invoice_doc_item(item) for item in items] | ||||||
|  | 						 | ||||||
|  | 	# 					if len(i_items) > 0: | ||||||
|  | 	# 						self.create_invoice(cust, i_items, "Abrechnung " + cust_doc.customer_name)	 | ||||||
|  | 	# 						invoice_count += 1 | ||||||
|  | 					 | ||||||
|  | 	# 				if cust_doc.billing_mode == "per Sales Order, remaining per Item Group": | ||||||
|  | 	# 					sales_order_items = [] | ||||||
|  | 	# 					item_list = items.copy() | ||||||
|  | 	# 					for item in item_list: | ||||||
|  | 	# 						if item.against_sales_order: | ||||||
|  | 	# 							invoice_doc_item = self.create_invoice_doc_item(item) | ||||||
|  | 	# 							sales_order_items.append(invoice_doc_item) | ||||||
|  | 	# 							items.remove(item) | ||||||
|  | 	# 					if len(sales_order_items) > 0: | ||||||
|  | 	# 						x = [i.sales_order for i in sales_order_items] | ||||||
|  | 	# 						a = list(set(x)) | ||||||
|  | 	# 						for el in a: | ||||||
|  | 	# 							sal_ord_it = [] | ||||||
|  | 	# 							for i in sales_order_items: | ||||||
|  | 	# 								if i.sales_order == el: | ||||||
|  | 	# 									sal_ord_it.append(i) | ||||||
|  | 	# 							self.create_invoice(cust, sal_ord_it, "Sales Order "+ el+ " " + cust_doc.customer_name) | ||||||
|  | 	# 							invoice_count += 1 | ||||||
|  | 	# 					for el in separation_item_groups: | ||||||
|  | 	# 						print(el[1]) | ||||||
|  | 	# 						a = [] | ||||||
|  | 	# 						it_list = items.copy() | ||||||
|  | 	# 						for item in it_list: | ||||||
|  | 	# 							if item.item_group in el[1]: | ||||||
|  | 	# 								invoice_doc_item = self.create_invoice_doc_item(item) | ||||||
|  | 	# 								a.append(invoice_doc_item) | ||||||
|  | 	# 								items.remove(item) | ||||||
|  | 	# 						if len(a) > 0: | ||||||
|  | 	# 							self.create_invoice(cust, a, el[0] + " " +cust_doc.customer_name) | ||||||
|  | 	# 							invoice_count += 1 | ||||||
|  | 	# 					i_items = [self.create_invoice_doc_item(item) for item in items] | ||||||
|  | 	# 					if len(i_items) > 0: | ||||||
|  | 	# 						self.create_invoice(cust, i_items, "Abrechnung " + cust_doc.customer_name)	 | ||||||
|  | 	# 						invoice_count += 1 | ||||||
|  | 	# 	frappe.msgprint("Für " + str(cust_count)+ " Kunden wurden " + str(invoice_count) + " Rechnungen erstellt.") | ||||||
|  | 	# 	self.date = datetime.today().strftime('%Y-%m-%d') | ||||||
|  | 	# 	self.invoice_count = invoice_count | ||||||
|  | 	# 	self.customer_count = cust_count | ||||||
|  | 	# 	log_str = "" | ||||||
|  | 	# 	for i in log_list: | ||||||
|  | 	# 		log_str += i + "\n" | ||||||
|  |                 | ||||||
|  | 	# 	self.log = log_str | ||||||
|  | 	# 	self.save()				 | ||||||
|  | 		 | ||||||
|  | 
 | ||||||
|  | 	# def create_invoice_doc_item(self, item): | ||||||
|  | 	# 	#Funktion kreiert Invoice Item aus den gegebenen Delivery Note Items | ||||||
|  | 	# 	invoice_doc_item = frappe.get_doc({ | ||||||
|  | 	# 					"doctype": "Sales Invoice Item", | ||||||
|  | 	# 					"item_code": item.item_code, | ||||||
|  | 	# 					"description": item.description, | ||||||
|  | 	# 					"qty": item.qty, | ||||||
|  | 	# 					"uom" : item.uom, | ||||||
|  | 	# 					"rate": item.rate, | ||||||
|  | 	# 					"sales_order": item.against_sales_order, | ||||||
|  | 	# 					"dn_detail": item.name, | ||||||
|  | 	# 					"parent": "delivery_note", | ||||||
|  | 	# 					"delivery_note": item.dn_detail | ||||||
|  | 	# 					}) | ||||||
|  | 	# 	return invoice_doc_item | ||||||
|  | 
 | ||||||
| 	@frappe.whitelist() | 	@frappe.whitelist() | ||||||
| 	def get_invoice_dict(self):  | 	def generate_invoices(self): | ||||||
| 		self.get_customer_asap_billing_mode() | 		self.get_customer_asap_billing_mode() | ||||||
| 		del_not = self.get_delivery_notes_for_invoicing() | 		delivery_notes = self.get_delivery_notes_for_invoicing() | ||||||
| 		cust_list = self.get_customer_for_invoicing(del_not) | 		customer_list = self.get_customer_for_invoicing(delivery_notes) | ||||||
| 		if self.customer:  | 		customer_list = [self.customer] if self.customer else customer_list | ||||||
| 			customer_list = [self.customer] |  | ||||||
| 		else: |  | ||||||
| 			customer_list = cust_list |  | ||||||
| 
 | 
 | ||||||
| 		print(len(customer_list)) | 		print(len(customer_list)) | ||||||
| 		cust_count = 0 | 		customer_count = 0 | ||||||
| 		invoice_count = 0 | 		invoice_count = 0 | ||||||
| 		log_list = [] | 		log_list = [] | ||||||
| 		for cust in customer_list: | 
 | ||||||
| 			cust_doc = frappe.get_doc("Customer",cust) | 		for customer in customer_list: | ||||||
| 			invoice_in_draft = frappe.get_all("Sales Invoice", filters = {"status" : "Draft", "customer": cust}) | 			customer_doc = frappe.get_doc("Customer", customer) | ||||||
| 			if len(invoice_in_draft) > 0: | 			if self.check_draft_invoices(customer): | ||||||
| 				log_list.append("Für Kunde"+ " "+ cust + " wurden keine Rechnungen erstellt, da noch nicht berechnete Rechnungen in Draft vorhanden")  | 				log_list.append(f"No invoices created for customer {customer} as draft invoices are present.") | ||||||
| 				continue | 				continue | ||||||
| 			else: | 
 | ||||||
| 				cust_count += 1 | 			customer_count += 1 | ||||||
| 				items = self.get_invoicing_items_for_cust(cust) | 			items = self.get_invoicing_items_for_customer(customer) | ||||||
| 			print(items) | 			print(items) | ||||||
| 				print("len Items") | 			print("Number of Items") | ||||||
| 			print(len(items)) | 			print(len(items)) | ||||||
| 				invoicing_items = [] |  | ||||||
| 
 | 
 | ||||||
| 				if cust_doc.billing_mode == "ASAP": | 			if customer_doc.billing_mode == "ASAP": | ||||||
| 					x = self.get_delivery_notes_for_customer(cust, del_not) | 				invoice_count += self.process_asap_billing(customer, delivery_notes, customer_doc) | ||||||
| 					for dn in x: | 			elif customer_doc.billing_mode == "Collective Bill": | ||||||
| 						item_doc = frappe.get_doc("Delivery Note", dn["name"])  | 				invoice_count += self.process_collective_billing(customer, items, customer_doc) | ||||||
| 						items = [self.create_invoice_doc_item(item) for item in item_doc.items] |  | ||||||
| 						for item in items: |  | ||||||
| 							item.delivery_note= dn["name"] |  | ||||||
| 
 |  | ||||||
| 						if len(items) > 0: |  | ||||||
| 							self.create_invoice(cust, items, "Abrechnung Lieferschein " + dn["name"]+ " " + cust_doc.customer_name) |  | ||||||
| 							invoice_count += 1 |  | ||||||
| 				elif cust_doc.billing_mode == "Collective Bill": |  | ||||||
| 					for item in items: |  | ||||||
| 						invoice_doc_item = self.create_invoice_doc_item(item) |  | ||||||
| 						invoicing_items.append(invoice_doc_item) |  | ||||||
| 					if len(invoicing_items) > 0: |  | ||||||
| 						self.create_invoice(cust, invoicing_items, "Sammelrechnung " + cust_doc.customer_name) |  | ||||||
| 						invoice_count += 1 |  | ||||||
| 			else: | 			else: | ||||||
| 					item_group_separation_dict = get_item_group_assignment_table(cust) | 				invoice_count += self.process_other_billing_modes(customer, items, customer_doc) | ||||||
| 					print(item_group_separation_dict) |  | ||||||
| 
 | 
 | ||||||
| 					separation_item_groups = [[item_group_separation_dict[x].item_group,item_group_separation_dict[x].filter]  for x in range(1, len(item_group_separation_dict) + 1) ]	 | 		self.finish_invoice_creation(customer_count, invoice_count, log_list) | ||||||
| 					if cust_doc.billing_mode == "per Item Group": | 
 | ||||||
| 						print("vor Separation") | 	@frappe.whitelist() | ||||||
| 						print(len(items)) | 	def generate_invoices_without_draft_items(self): | ||||||
| 						for el in separation_item_groups: | 		self.get_customer_asap_billing_mode() | ||||||
| 							print(el[1]) | 		delivery_notes = self.get_delivery_notes_for_invoicing() | ||||||
|  | 		customer_list = self.get_customer_for_invoicing(delivery_notes) | ||||||
|  | 		customer_list = [self.customer] if self.customer else customer_list | ||||||
|  | 
 | ||||||
|  | 		print(len(customer_list)) | ||||||
|  | 		customer_count = 0 | ||||||
|  | 		invoice_count = 0 | ||||||
|  | 		log_list = [] | ||||||
|  | 
 | ||||||
|  | 		for customer in customer_list: | ||||||
|  | 			customer_doc = frappe.get_doc("Customer", customer) | ||||||
|  | 			draft_items = self.get_draft_items_for_customer(customer) | ||||||
|  | 			items = self.get_invoicing_items_for_customer(customer) | ||||||
|  | 			items = [item for item in items if item.name not in draft_items] | ||||||
|  | 
 | ||||||
|  | 			if not items: | ||||||
|  | 				log_list.append(f"No invoices created for customer {customer} as all items are in draft invoices.") | ||||||
|  | 				continue | ||||||
|  | 
 | ||||||
|  | 			customer_count += 1 | ||||||
| 			print(items) | 			print(items) | ||||||
| 							a = [] | 			print("Number of Items") | ||||||
| 							items_list = items.copy() |  | ||||||
| 							for item in items_list: |  | ||||||
| 							# for i in item_name: |  | ||||||
| 							# 	item = filter(lambda item: item['name'] == i, items) |  | ||||||
| 								print(item) |  | ||||||
| 
 |  | ||||||
| 								#print(item.item_group) |  | ||||||
| 								if item.item_group in el[1]: |  | ||||||
| 									print(True) |  | ||||||
| 									invoice_doc_item = self.create_invoice_doc_item(item) |  | ||||||
| 									print(invoice_doc_item) |  | ||||||
| 									a.append(invoice_doc_item) |  | ||||||
| 									items.remove(item) |  | ||||||
| 									print(len(a)) |  | ||||||
| 			print(len(items)) | 			print(len(items)) | ||||||
| 
 | 
 | ||||||
|  | 			if customer_doc.billing_mode == "ASAP": | ||||||
|  | 				invoice_count += self.process_asap_billing(customer, delivery_notes, customer_doc, items) | ||||||
|  | 			elif customer_doc.billing_mode == "Collective Bill": | ||||||
|  | 				invoice_count += self.process_collective_billing(customer, items, customer_doc) | ||||||
| 			else: | 			else: | ||||||
| 									print(False) | 				invoice_count += self.process_other_billing_modes(customer, items, customer_doc) | ||||||
| 							if len(a) > 0: |  | ||||||
| 								self.create_invoice(cust, a, el[0] + " " +cust_doc.customer_name) |  | ||||||
| 								invoice_count +=1 |  | ||||||
| 							print("nach Separation") |  | ||||||
| 							print(len(items))	 |  | ||||||
| 						i_items = [self.create_invoice_doc_item(item) for item in items] |  | ||||||
| 
 | 
 | ||||||
| 						if len(i_items) > 0: | 		self.finish_invoice_creation(customer_count, invoice_count, log_list) | ||||||
| 							self.create_invoice(cust, i_items, "Abrechnung " + cust_doc.customer_name)	 | 
 | ||||||
|  | 	def check_draft_invoices(self, customer): | ||||||
|  | 		draft_invoices = frappe.get_all("Sales Invoice", filters={"status": "Draft", "customer": customer}) | ||||||
|  | 		return len(draft_invoices) > 0 | ||||||
|  | 
 | ||||||
|  | 	def get_draft_items_for_customer(self, customer): | ||||||
|  | 		draft_items = frappe.get_all("Sales Invoice Item", filters={"parentfield": "items", "parent": ["in", frappe.get_all("Sales Invoice", filters={"status": "Draft", "customer": customer}, pluck="name")]}) | ||||||
|  | 		return [item.dn_detail for item in draft_items] | ||||||
|  | 
 | ||||||
|  | 	def process_asap_billing(self, customer, delivery_notes, customer_doc, items=None): | ||||||
|  | 		invoice_count = 0 | ||||||
|  | 		deliveries = self.get_delivery_notes_for_customer(customer, delivery_notes) | ||||||
|  | 		for delivery in deliveries: | ||||||
|  | 			delivery_doc = frappe.get_doc("Delivery Note", delivery["name"]) | ||||||
|  | 			items = items or [self.create_invoice_doc_item(delivery_item) for delivery_item in delivery_doc.items] | ||||||
|  | 			for item in items: | ||||||
|  | 				item.delivery_note = delivery["name"] | ||||||
|  | 			if items: | ||||||
|  | 				self.create_invoice(customer, items, f"Invoice for Delivery Note {delivery['name']} {customer_doc.customer_name}") | ||||||
|  | 				invoice_count += 1 | ||||||
|  | 		return invoice_count | ||||||
|  | 
 | ||||||
|  | 	def process_collective_billing(self, customer, items, customer_doc): | ||||||
|  | 		invoice_items = [self.create_invoice_doc_item(item) for item in items] | ||||||
|  | 		if invoice_items: | ||||||
|  | 			self.create_invoice(customer, invoice_items, f"Collective Bill {customer_doc.customer_name}") | ||||||
|  | 			return 1 | ||||||
|  | 		return 0 | ||||||
|  | 
 | ||||||
|  | 	def process_other_billing_modes(self, customer, items, customer_doc): | ||||||
|  | 		invoice_count = 0 | ||||||
|  | 		item_group_separation_dict = get_item_group_assignment_table(customer) | ||||||
|  | 		separation_item_groups = [[item_group_separation_dict[x].item_group, item_group_separation_dict[x].filter] for x in range(1, len(item_group_separation_dict) + 1)] | ||||||
|  | 		 | ||||||
|  | 		if customer_doc.billing_mode == "per Item Group": | ||||||
|  | 			invoice_count += self.process_per_item_group(customer, items, separation_item_groups, customer_doc) | ||||||
|  | 		elif customer_doc.billing_mode == "per Sales Order, remaining per Item Group": | ||||||
|  | 			invoice_count += self.process_per_sales_order_remaining_per_item_group(customer, items, separation_item_groups, customer_doc) | ||||||
|  | 		return invoice_count | ||||||
|  | 
 | ||||||
|  | 	def process_per_item_group(self, customer, items, separation_item_groups, customer_doc): | ||||||
|  | 		invoice_count = 0 | ||||||
|  | 		for group in separation_item_groups: | ||||||
|  | 			group_items, items = self.separate_items_by_group(items, group[1]) | ||||||
|  | 			if group_items: | ||||||
|  | 				self.create_invoice(customer, group_items, f"{group[0]} {customer_doc.customer_name}") | ||||||
| 				invoice_count += 1 | 				invoice_count += 1 | ||||||
| 
 | 
 | ||||||
| 					if cust_doc.billing_mode == "per Sales Order, remaining per Item Group": | 		remaining_items = [self.create_invoice_doc_item(item) for item in items] | ||||||
| 						sales_order_items = [] | 		if remaining_items: | ||||||
| 						item_list = items.copy() | 			self.create_invoice(customer, remaining_items, f"Invoice {customer_doc.customer_name}") | ||||||
| 						for item in item_list: | 			invoice_count += 1 | ||||||
| 							if item.against_sales_order: | 
 | ||||||
| 								invoice_doc_item = self.create_invoice_doc_item(item) | 		return invoice_count | ||||||
| 								sales_order_items.append(invoice_doc_item) | 
 | ||||||
|  | 	def process_per_sales_order_remaining_per_item_group(self, customer, items, separation_item_groups, customer_doc): | ||||||
|  | 		invoice_count = 0 | ||||||
|  | 		sales_order_items, items = self.separate_sales_order_items(items) | ||||||
|  | 		invoice_count += self.create_sales_order_invoices(customer, sales_order_items, customer_doc) | ||||||
|  | 
 | ||||||
|  | 		for group in separation_item_groups: | ||||||
|  | 			group_items, items = self.separate_items_by_group(items, group[1]) | ||||||
|  | 			if group_items: | ||||||
|  | 				self.create_invoice(customer, group_items, f"{group[0]} {customer_doc.customer_name}") | ||||||
|  | 				invoice_count += 1 | ||||||
|  | 
 | ||||||
|  | 		remaining_items = [self.create_invoice_doc_item(item) for item in items] | ||||||
|  | 		if remaining_items: | ||||||
|  | 			self.create_invoice(customer, remaining_items, f"Invoice {customer_doc.customer_name}") | ||||||
|  | 			invoice_count += 1 | ||||||
|  | 
 | ||||||
|  | 		return invoice_count | ||||||
|  | 
 | ||||||
|  | 	def separate_items_by_group(self, items, group_filter): | ||||||
|  | 		group_items = [] | ||||||
|  | 		remaining_items = items.copy() | ||||||
|  | 		for item in remaining_items: | ||||||
|  | 			if item.item_group in group_filter: | ||||||
|  | 				group_items.append(self.create_invoice_doc_item(item)) | ||||||
| 				items.remove(item) | 				items.remove(item) | ||||||
| 						if len(sales_order_items) > 0: | 		return group_items, items | ||||||
| 							x = [i.sales_order for i in sales_order_items] |  | ||||||
| 							a = list(set(x)) |  | ||||||
| 							for el in a: |  | ||||||
| 								sal_ord_it = [] |  | ||||||
| 								for i in sales_order_items: |  | ||||||
| 									if i.sales_order == el: |  | ||||||
| 										sal_ord_it.append(i) |  | ||||||
| 								self.create_invoice(cust, sal_ord_it, "Sales Order "+ el+ " " + cust_doc.customer_name) |  | ||||||
| 								invoice_count += 1 |  | ||||||
| 						for el in separation_item_groups: |  | ||||||
| 							print(el[1]) |  | ||||||
| 							a = [] |  | ||||||
| 							it_list = items.copy() |  | ||||||
| 							for item in it_list: |  | ||||||
| 								if item.item_group in el[1]: |  | ||||||
| 									invoice_doc_item = self.create_invoice_doc_item(item) |  | ||||||
| 									a.append(invoice_doc_item) |  | ||||||
| 									items.remove(item) |  | ||||||
| 							if len(a) > 0: |  | ||||||
| 								self.create_invoice(cust, a, el[0] + " " +cust_doc.customer_name) |  | ||||||
| 								invoice_count += 1 |  | ||||||
| 						i_items = [self.create_invoice_doc_item(item) for item in items] |  | ||||||
| 						if len(i_items) > 0: |  | ||||||
| 							self.create_invoice(cust, i_items, "Abrechnung " + cust_doc.customer_name)	 |  | ||||||
| 							invoice_count += 1 |  | ||||||
| 		frappe.msgprint("Für " + str(cust_count)+ " Kunden wurden " + str(invoice_count) + " Rechnungen erstellt.") |  | ||||||
| 		self.date = datetime.today().strftime('%Y-%m-%d') |  | ||||||
| 		self.invoice_count = invoice_count |  | ||||||
| 		self.customer_count = cust_count |  | ||||||
| 		log_str = "" |  | ||||||
| 		for i in log_list: |  | ||||||
| 			log_str += i + "\n" |  | ||||||
| 
 | 
 | ||||||
| 		self.log = log_str | 	def separate_sales_order_items(self, items): | ||||||
| 		self.save()				 | 		sales_order_items = [self.create_invoice_doc_item(item) for item in items if item.against_sales_order] | ||||||
|  | 		remaining_items = [item for item in items if not item.against_sales_order] | ||||||
|  | 		return sales_order_items, remaining_items | ||||||
| 
 | 
 | ||||||
|  | 	def create_sales_order_invoices(self, customer, sales_order_items, customer_doc): | ||||||
|  | 		invoice_count = 0 | ||||||
|  | 		sales_orders = set(item.sales_order for item in sales_order_items) | ||||||
|  | 		for order in sales_orders: | ||||||
|  | 			order_items = [item for item in sales_order_items if item.sales_order == order] | ||||||
|  | 			self.create_invoice(customer, order_items, f"Sales Order {order} {customer_doc.customer_name}") | ||||||
|  | 			invoice_count += 1 | ||||||
|  | 		return invoice_count | ||||||
| 
 | 
 | ||||||
| 	def create_invoice_doc_item(self, item): | 	def create_invoice_doc_item(self, item): | ||||||
| 		#Funktion kreiert Invoice Item aus den gegebenen Delivery Note Items | 		return frappe.get_doc({ | ||||||
| 		invoice_doc_item = frappe.get_doc({ |  | ||||||
| 			"doctype": "Sales Invoice Item", | 			"doctype": "Sales Invoice Item", | ||||||
| 			"item_code": item.item_code, | 			"item_code": item.item_code, | ||||||
| 			"description": item.description, | 			"description": item.description, | ||||||
| 			"qty": item.qty, | 			"qty": item.qty, | ||||||
| 						"uom" : item.uom, | 			"uom": item.uom, | ||||||
| 			"rate": item.rate, | 			"rate": item.rate, | ||||||
| 			"sales_order": item.against_sales_order, | 			"sales_order": item.against_sales_order, | ||||||
| 			"dn_detail": item.name, | 			"dn_detail": item.name, | ||||||
| 			"parent": "delivery_note", | 			"parent": "delivery_note", | ||||||
| 			"delivery_note": item.dn_detail | 			"delivery_note": item.dn_detail | ||||||
| 		}) | 		}) | ||||||
| 		return invoice_doc_item | 
 | ||||||
|  | 	def finish_invoice_creation(self, customer_count, invoice_count, log_list): | ||||||
|  | 		frappe.msgprint(f"{customer_count} customers had {invoice_count} invoices created.") | ||||||
|  | 		self.date = datetime.today().strftime('%Y-%m-%d') | ||||||
|  | 		self.invoice_count = invoice_count | ||||||
|  | 		self.customer_count = customer_count | ||||||
|  | 		self.log = "\n".join(log_list) | ||||||
|  | 		self.save() | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	def create_invoice(self,cust,invoice_doc_items,title): | 	def create_invoice(self,cust,invoice_doc_items,title): | ||||||
| @ -400,6 +587,23 @@ class AutoInvoiceGenerator(Document): | |||||||
| 		 | 		 | ||||||
| 		new_billing_month = "{:02d}.{}".format(month, year) | 		new_billing_month = "{:02d}.{}".format(month, year) | ||||||
| 		return new_billing_month | 		return new_billing_month | ||||||
|  | 	@frappe.whitelist() | ||||||
|  | 	def get_invoice_despite_draft(self): | ||||||
|  | 		self.get_customer_asap_billing_mode() | ||||||
|  | 		del_not = self.get_delivery_notes_for_invoicing() | ||||||
|  | 		cust_list = self.get_customer_for_invoicing(del_not) | ||||||
|  | 		if self.customer:  | ||||||
|  | 			customer_list = [self.customer] | ||||||
|  | 		else: | ||||||
|  | 			customer_list = cust_list | ||||||
|  | 
 | ||||||
|  | 		print(len(customer_list)) | ||||||
|  | 		log_list = [] | ||||||
|  | 		for cust in customer_list: | ||||||
|  | 			cust_doc = frappe.get_doc("Customer",cust) | ||||||
|  | 			invoice_in_draft = frappe.get_all("Sales Invoice", filters = {"status" : "Draft", "customer": cust}) | ||||||
|  | 			if len(invoice_in_draft) > 0: | ||||||
|  | 				log_list.append("Für Kunde"+ " "+ cust + " wurden keine Rechnungen erstellt, da noch nicht berechnete Rechnungen in Draft vorhanden")  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user