mirror of
https://github.com/itsdave-de/msp.git
synced 2025-05-06 15:35:12 +02:00
Auto Invoice Generator Anpassung
This commit is contained in:
parent
9141df2e63
commit
f0fe2582dd
@ -7,7 +7,6 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"invoicing_grouped_by",
|
|
||||||
"close_invoiced_delivery_notes_section",
|
"close_invoiced_delivery_notes_section",
|
||||||
"close",
|
"close",
|
||||||
"invoices_from_delivery_notes_section",
|
"invoices_from_delivery_notes_section",
|
||||||
@ -16,15 +15,10 @@
|
|||||||
"statistics",
|
"statistics",
|
||||||
"date",
|
"date",
|
||||||
"invoice_count",
|
"invoice_count",
|
||||||
"customer_count"
|
"customer_count",
|
||||||
|
"log"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
|
||||||
"fieldname": "invoicing_grouped_by",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"label": "Invoicing grouped by",
|
|
||||||
"options": "\nService and Goods\nService and Goods and Sales Order"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "close_invoiced_delivery_notes_section",
|
"fieldname": "close_invoiced_delivery_notes_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@ -75,11 +69,17 @@
|
|||||||
"fieldname": "statistics",
|
"fieldname": "statistics",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Statistics"
|
"label": "Statistics"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "log",
|
||||||
|
"fieldtype": "Small Text",
|
||||||
|
"label": "Log"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-09-02 11:56:18.512522",
|
"migration_hash": "81a435d8fdde574c14c22be58f9e32ca",
|
||||||
|
"modified": "2022-09-22 14:23:33.413375",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "MSP",
|
"module": "MSP",
|
||||||
"name": "Auto Invoice Generator",
|
"name": "Auto Invoice Generator",
|
||||||
|
@ -8,6 +8,7 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.accounts.party import set_taxes as party_st
|
from erpnext.accounts.party import set_taxes as party_st
|
||||||
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
||||||
|
from msp.billing_tools import get_item_group_assignment_table
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from frappe import ValidationError, _
|
from frappe import ValidationError, _
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ class AutoInvoiceGenerator(Document):
|
|||||||
frappe.db.set_value("Delivery Note", pos, "status", "Closed")
|
frappe.db.set_value("Delivery Note", pos, "status", "Closed")
|
||||||
frappe.msgprint( str(count)+ " delivery notes were closed")
|
frappe.msgprint( str(count)+ " delivery notes were closed")
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_delivery_notes_for_invoicing(self):
|
def get_delivery_notes_for_invoicing(self):
|
||||||
|
|
||||||
@ -41,10 +43,9 @@ class AutoInvoiceGenerator(Document):
|
|||||||
#filters = {"status" : "to bill","is_return": 0, "project": ""}
|
#filters = {"status" : "to bill","is_return": 0, "project": ""}
|
||||||
delivery_notes_list = frappe.get_all("Delivery Note", filters = filters, fields = ["name", "customer", "project"])
|
delivery_notes_list = frappe.get_all("Delivery Note", filters = filters, fields = ["name", "customer", "project"])
|
||||||
print(len(delivery_notes_list))
|
print(len(delivery_notes_list))
|
||||||
dl = [x.name for x in delivery_notes_list if x.project]
|
#dl = [x.name for x in delivery_notes_list if x.project]
|
||||||
print(dl)
|
#print(dl)
|
||||||
print(len(dl))
|
#print(len(dl))
|
||||||
|
|
||||||
return delivery_notes_list
|
return delivery_notes_list
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_customer_for_invoicing(self, delivery_note):
|
def get_customer_for_invoicing(self, delivery_note):
|
||||||
@ -60,9 +61,22 @@ class AutoInvoiceGenerator(Document):
|
|||||||
|
|
||||||
return customer_list_exc_duplicate
|
return customer_list_exc_duplicate
|
||||||
|
|
||||||
def get_delivery_notes_for_customer(self, cust, delivery_notes):
|
def get_customer_asap_billing_mode(self):
|
||||||
|
del_not = self.get_delivery_notes_for_invoicing()
|
||||||
|
cust_list = self.get_customer_for_invoicing(del_not)
|
||||||
|
filters = {"name": ["in",cust_list],
|
||||||
|
"billing_mode": "ASAP"}
|
||||||
|
cust_list_asap = frappe.get_all("Customer", filters = filters )
|
||||||
|
asap_cust = [x.name for x in cust_list_asap]
|
||||||
|
print(asap_cust)
|
||||||
|
return asap_cust
|
||||||
|
|
||||||
#Funktion listet alle Lieferscheine für den jeweiligen Kunden auf
|
def get_asap_invoices(self, cust_list):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_delivery_notes_for_customer(self, cust, delivery_notes):
|
||||||
|
#Funktion listet alle Lieferscheine für den jeweiligen Kunden auf
|
||||||
cust_del_note = []
|
cust_del_note = []
|
||||||
|
|
||||||
for el in delivery_notes:
|
for el in delivery_notes:
|
||||||
@ -71,12 +85,34 @@ class AutoInvoiceGenerator(Document):
|
|||||||
cust_del_note.append(el)
|
cust_del_note.append(el)
|
||||||
|
|
||||||
return cust_del_note
|
return cust_del_note
|
||||||
@frappe.whitelist()
|
|
||||||
def get_invoice_dict(self):
|
|
||||||
|
|
||||||
|
def get_invoicing_items_for_cust(self,cust):
|
||||||
|
#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()
|
||||||
print(del_not)
|
cust_doc = frappe.get_doc("Customer",cust)
|
||||||
|
delivery_note_list = self.get_delivery_notes_for_customer(cust,del_not)
|
||||||
|
#print(delivery_note_list)
|
||||||
|
if len(delivery_note_list) < 1:
|
||||||
|
frappe.msgprint("Keine abrechnenbaren Lieferscheine vorhanden")
|
||||||
|
else:
|
||||||
|
items = []
|
||||||
|
|
||||||
|
for dn in delivery_note_list:
|
||||||
|
|
||||||
|
item_doc = frappe.get_doc("Delivery Note", dn["name"])
|
||||||
|
for item in item_doc.items:
|
||||||
|
print(item.item_group)
|
||||||
|
item.dn_detail= dn["name"]
|
||||||
|
print("item.dn_detail")
|
||||||
|
print(item.dn_detail)
|
||||||
|
items.append(item)
|
||||||
|
return items
|
||||||
|
|
||||||
|
@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)
|
cust_list = self.get_customer_for_invoicing(del_not)
|
||||||
if self.customer:
|
if self.customer:
|
||||||
customer_list = [self.customer]
|
customer_list = [self.customer]
|
||||||
@ -87,91 +123,105 @@ class AutoInvoiceGenerator(Document):
|
|||||||
cust_count = 0
|
cust_count = 0
|
||||||
invoice_count = 0
|
invoice_count = 0
|
||||||
for cust in customer_list:
|
for cust in customer_list:
|
||||||
print(cust)
|
|
||||||
cust_doc = frappe.get_doc("Customer",cust)
|
cust_doc = frappe.get_doc("Customer",cust)
|
||||||
invoice_in_draft = frappe.get_all("Sales Invoice", filters = {"status" : "Draft", "customer": cust})
|
invoice_in_draft = frappe.get_all("Sales Invoice", filters = {"status" : "Draft", "customer": cust})
|
||||||
if len(invoice_in_draft) > 0:
|
if len(invoice_in_draft) > 0:
|
||||||
print("nicht bearbeitet")
|
self.log = "Für Kunde"+ " "+ cust + " wurden keine Rechnungen erstellt, da noch nicht berechnete Rechnungen in Draft vorhanden"
|
||||||
print(cust)
|
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
cust_count += 1
|
cust_count += 1
|
||||||
#if self.invoicing_grouped_by == "None":
|
items = self.get_invoicing_items_for_cust(cust)
|
||||||
|
print(items)
|
||||||
|
invoicing_items = []
|
||||||
|
|
||||||
delivery_note_list = self.get_delivery_notes_for_customer(cust,del_not)
|
if cust_doc.billing_mode == "ASAP":
|
||||||
#print(delivery_note_list)
|
x = self.get_delivery_notes_for_customer(cust, del_not)
|
||||||
if len(delivery_note_list) < 1:
|
for dn in x:
|
||||||
frappe.msgprint("Keine abrechnenbaren Lieferscheine vorhanden")
|
item_doc = frappe.get_doc("Delivery Note", dn["name"])
|
||||||
sales_order_items = []
|
items = [self.create_invoice_doc_item(item) for item in item_doc.items]
|
||||||
service_items = []
|
if len(items) > 0:
|
||||||
goods_items =[]
|
self.create_invoice(cust, items, "Abrechnung Lieferschein " + dn["name"]+ " " + cust_doc.customer_name)
|
||||||
for dn in delivery_note_list:
|
invoice_count += 1
|
||||||
|
elif cust_doc.billing_mode == "Collective Bill":
|
||||||
item_doc = frappe.get_doc("Delivery Note", dn["name"])
|
for item in items:
|
||||||
|
invoice_doc_item = self.create_invoice_doc_item(item)
|
||||||
for item in item_doc.items:
|
invoicing_items.append(invoice_doc_item)
|
||||||
print(item.item_group)
|
if len(invoicing_items) > 0:
|
||||||
invoice_doc_item = frappe.get_doc({
|
self.create_invoice(cust, invoicing_items, "Sammelrechnung " + cust_doc.customer_name)
|
||||||
"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": dn["name"]
|
|
||||||
|
|
||||||
})
|
|
||||||
print(item.dn_detail)
|
|
||||||
print(dn["name"])
|
|
||||||
print(item.qty)
|
|
||||||
print(item.uom)
|
|
||||||
if item.item_group == "Dienstleistungen" or item.item_group == "Anfahrten" or item.item_group == "Arbeitszeiten Techniker" or item.item_group == "Zuschläge" or item.item_group == "Anwendungsentwicklung":
|
|
||||||
service_items.append(invoice_doc_item)
|
|
||||||
elif item.against_sales_order:
|
|
||||||
sales_order_items.append(invoice_doc_item)
|
|
||||||
else:
|
|
||||||
goods_items.append(invoice_doc_item)
|
|
||||||
|
|
||||||
if self.invoicing_grouped_by == "Service and Goods and Sales Order":
|
|
||||||
self.create_invoice(cust, goods_items, "Ware " + cust_doc.customer_name)
|
|
||||||
if len(goods_items) > 0:
|
|
||||||
invoice_count += 1
|
|
||||||
self.create_invoice(cust, service_items, "Dienstleistung " + cust_doc.customer_name)
|
|
||||||
if len(service_items) > 0:
|
|
||||||
invoice_count += 1
|
|
||||||
#self.create_invoice(cust, sales_order_items, "Sales Order " + cust_doc.customer_name)
|
|
||||||
if len(sales_order_items) > 0:
|
|
||||||
print("Sales Order Check")
|
|
||||||
x = [i.sales_order for i in sales_order_items]
|
|
||||||
print(x)
|
|
||||||
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
|
invoice_count += 1
|
||||||
elif self.invoicing_grouped_by == "Service and Goods":
|
else:
|
||||||
invoice_item = sales_order_items + goods_items
|
item_group_separation_dict = get_item_group_assignment_table(cust)
|
||||||
self.create_invoice(cust, invoice_item, "Ware " + cust_doc.customer_name)
|
print(item_group_separation_dict)
|
||||||
if len(invoice_item) > 0:
|
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) ]
|
||||||
invoice_count += 1
|
if cust_doc.billing_mode == "per Item Group":
|
||||||
self.create_invoice(cust, service_items, "Dienstleistung " + cust_doc.customer_name)
|
for el in separation_item_groups:
|
||||||
if len(service_items) >0:
|
print(el[1])
|
||||||
invoice_count += 1
|
a = []
|
||||||
else:
|
for item in items:
|
||||||
invoice_item = sales_order_items + service_items + goods_items
|
if item.item_group in el[1]:
|
||||||
self.create_invoice(cust, invoice_item, "Dienstleistung und Ware "+ cust_doc.customer_name)
|
invoice_doc_item = self.create_invoice_doc_item(item)
|
||||||
if len(invoice_item) > 0:
|
a.append(invoice_doc_item)
|
||||||
invoice_count += 1
|
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
|
||||||
|
if cust_doc.billing_mode == "per Sales Order, remaining per Item Group":
|
||||||
|
sales_order_items = []
|
||||||
|
for item in items:
|
||||||
|
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 = []
|
||||||
|
for item in items:
|
||||||
|
if item.item_group in el[1]:
|
||||||
|
invoice_doc_item = self.create_invoice_doc_item(item)
|
||||||
|
a.append(invoice_doc_item)
|
||||||
|
items.remove(item)
|
||||||
|
self.create_invoice(cust, a, el[0] + " " +cust_doc.customer_name)
|
||||||
|
|
||||||
|
i_items = [self.create_invoice_doc_item(item) for item in items]
|
||||||
|
self.create_invoice(cust, i_items, "Abrechnung " + cust_doc.customer_name)
|
||||||
frappe.msgprint("Für " + str(cust_count)+ " Kunden wurden " + str(invoice_count) + " Rechnungen erstellt.")
|
frappe.msgprint("Für " + str(cust_count)+ " Kunden wurden " + str(invoice_count) + " Rechnungen erstellt.")
|
||||||
self.date = datetime.today().strftime('%Y-%m-%d')
|
self.date = datetime.today().strftime('%Y-%m-%d')
|
||||||
self.invoice_count = invoice_count
|
self.invoice_count = invoice_count
|
||||||
self.customer_count = cust_count
|
self.customer_count = cust_count
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
def create_invoice(self,cust,invoice_doc_items,title):
|
def create_invoice(self,cust,invoice_doc_items,title):
|
||||||
invoice_doc = frappe.get_doc({
|
invoice_doc = frappe.get_doc({
|
||||||
"doctype": "Sales Invoice",
|
"doctype": "Sales Invoice",
|
||||||
@ -181,6 +231,7 @@ class AutoInvoiceGenerator(Document):
|
|||||||
"items": invoice_doc_items
|
"items": invoice_doc_items
|
||||||
})
|
})
|
||||||
if len(invoice_doc_items)>0:
|
if len(invoice_doc_items)>0:
|
||||||
|
self.validate_items(invoice_doc_items)
|
||||||
settings_doc = frappe.get_single("Auto Invoice Generator Settings")
|
settings_doc = frappe.get_single("Auto Invoice Generator Settings")
|
||||||
customer_doc = frappe.get_doc("Customer", cust )
|
customer_doc = frappe.get_doc("Customer", cust )
|
||||||
|
|
||||||
@ -206,4 +257,12 @@ class AutoInvoiceGenerator(Document):
|
|||||||
invoice_doc.append("taxes", new_tax)
|
invoice_doc.append("taxes", new_tax)
|
||||||
invoice_doc.save()
|
invoice_doc.save()
|
||||||
|
|
||||||
|
def validate_items(self,item_list):
|
||||||
|
print("len(item_list):")
|
||||||
|
print(len(item_list))
|
||||||
|
print("len(set(item_list)):")
|
||||||
|
print(len(set(item_list)))
|
||||||
|
if len(item_list) == len(set(item_list)):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
frappe.msgprint("Rechnungspositionen doppelt")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user