Auto Invoice Generator

This commit is contained in:
Beate Trzensiok 2022-08-29 14:30:04 +02:00
parent e5286ee085
commit 90516857ce
10 changed files with 402 additions and 0 deletions

View File

@ -0,0 +1,8 @@
// Copyright (c) 2022, itsdave GmbH and contributors
// For license information, please see license.txt
frappe.ui.form.on('Auto Invoice Generator', {
// refresh: function(frm) {
// }
});

View File

@ -0,0 +1,97 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "AUTOINV-.#####",
"creation": "2022-08-29 13:47:37.295147",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"invoicing_grouped_by",
"close_invoiced_delivery_notes_section",
"close",
"invoices_from_delivery_notes_section",
"customer",
"get_invoice",
"date",
"invoice_count",
"customer_count"
],
"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",
"fieldtype": "Section Break",
"label": "Close invoiced Delivery Notes"
},
{
"fieldname": "close",
"fieldtype": "Button",
"label": "Close"
},
{
"fieldname": "invoices_from_delivery_notes_section",
"fieldtype": "Section Break",
"label": "Invoices from delivery notes"
},
{
"fieldname": "customer",
"fieldtype": "Link",
"label": "Customer",
"options": "Customer"
},
{
"fieldname": "get_invoice",
"fieldtype": "Button",
"label": "Get Invoice",
"options": "get_invoice_dict"
},
{
"fieldname": "date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Date"
},
{
"fieldname": "invoice_count",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Invoice count"
},
{
"fieldname": "customer_count",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Customer count"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2022-08-29 14:26:06.333736",
"modified_by": "Administrator",
"module": "MSP",
"name": "Auto Invoice Generator",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -0,0 +1,209 @@
# Copyright (c) 2022, itsdave GmbH and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
from doctest import debug
import frappe
from frappe.model.document import Document
from erpnext.accounts.party import set_taxes as party_st
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
from datetime import datetime
from frappe import ValidationError, _
class AutoInvoiceGenerator(Document):
@frappe.whitelist()
def close_invoiced_delivery_notes(self):
dns = frappe.get_all("Delivery Note", filters={"status": "To Bill"})
print(len(dns))
dns_to_close = []
for el in dns:
try:
make_sales_invoice(el["name"])
except ValidationError as e:
if str(e) == _("All these items have already been Invoiced/Returned"):
print(_("All these items have already been Invoiced/Returned") + " in: " + el["name"])
dns_to_close.append(el["name"])
count = 0
print(dns_to_close)
for pos in dns_to_close:
count +=1
frappe.db.set_value("Delivery Note", pos, "status", "Closed")
frappe.msgprint( str(count)+ " delivery notes were closed")
@frappe.whitelist()
def get_delivery_notes_for_invoicing(self):
#Funktion soll eine Liste aller Lieferscheine zurückgeben die abzurechnen sind
filters = {"status" : "to bill","is_return": 0, "project": "", "blocked_for_billing": 0 }
#filters = {"status" : "to bill","is_return": 0, "project": ""}
delivery_notes_list = frappe.get_all("Delivery Note", filters = filters, fields = ["name", "customer", "project"])
print(len(delivery_notes_list))
dl = [x.name for x in delivery_notes_list if x.project]
print(dl)
print(len(dl))
return delivery_notes_list
@frappe.whitelist()
def get_customer_for_invoicing(self, delivery_note):
#Funktion erstellt eine Liste von Kunden für die Rechnungen erstellt werden sollen
delivery_notes = self.get_delivery_notes_for_invoicing()
customer_list = [x.customer for x in delivery_notes]
customer_list_exc_duplicate = list(set(customer_list))
#print(customer_list_exc_duplicate)
return customer_list_exc_duplicate
def get_delivery_notes_for_customer(self, cust, delivery_notes):
#Funktion listet alle Lieferscheine für den jeweiligen Kunden auf
cust_del_note = []
for el in delivery_notes:
if el["customer"] == cust:
cust_del_note.append(el)
return cust_del_note
@frappe.whitelist()
def get_invoice_dict(self):
del_not = self.get_delivery_notes_for_invoicing()
print(del_not)
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
for cust in customer_list:
print(cust)
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:
print("nicht bearbeitet")
print(cust)
continue
else:
cust_count += 1
#if self.invoicing_grouped_by == "None":
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")
sales_order_items = []
service_items = []
goods_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)
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": 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 == "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
elif self.invoicing_grouped_by == "Service and Goods":
invoice_item = sales_order_items + goods_items
self.create_invoice(cust, invoice_item, "Ware " + cust_doc.customer_name)
if len(invoice_item) > 0:
invoice_count += 1
self.create_invoice(cust, service_items, "Dienstleistung " + cust_doc.customer_name)
if len(service_items) >0:
invoice_count += 1
else:
invoice_item = sales_order_items + service_items + goods_items
self.create_invoice(cust, invoice_item, "Dienstleistung und Ware "+ cust_doc.customer_name)
if len(invoice_item) > 0:
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
def create_invoice(self,cust,invoice_doc_items,title):
invoice_doc = frappe.get_doc({
"doctype": "Sales Invoice",
"title": title,
"customer": cust,
"company": frappe.get_doc("Global Defaults").default_company,
"items": invoice_doc_items
})
if len(invoice_doc_items)>0:
settings_doc = frappe.get_single("Auto Invoice Generator Settings")
customer_doc = frappe.get_doc("Customer", cust )
if customer_doc.payment_terms:
invoice_doc.payment_terms_template = customer_doc.payment_terms
else:
invoice_doc.payment_terms_template = settings_doc.payment_terms_template
invoice_doc.tc_name = settings_doc.tc_name
tac_doc = frappe.get_doc("Terms and Conditions", settings_doc.tc_name)
invoice_doc.terms = tac_doc.terms
invoice_doc.taxes_and_charges = party_st(invoice_doc.customer, "Customer", invoice_doc.posting_date, invoice_doc.company)
taxes = frappe.get_doc("Sales Taxes and Charges Template", settings_doc.taxes_and_charges).taxes
for tax in taxes:
new_tax = frappe.get_doc({
"doctype": "Sales Taxes and Charges",
"charge_type": tax.charge_type,
"account_head": tax.account_head,
"rate": tax.rate,
"description": tax.description
})
invoice_doc.append("taxes", new_tax)
invoice_doc.save()

View File

@ -0,0 +1,8 @@
# Copyright (c) 2022, itsdave GmbH and Contributors
# See license.txt
# import frappe
import unittest
class TestAutoInvoiceGenerator(unittest.TestCase):
pass

View File

@ -0,0 +1,8 @@
// Copyright (c) 2022, itsdave GmbH and contributors
// For license information, please see license.txt
frappe.ui.form.on('Auto Invoice Generator Settings', {
// refresh: function(frm) {
// }
});

View File

@ -0,0 +1,56 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2022-08-29 14:02:35.295304",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"tc_name",
"payment_terms_template",
"taxes_and_charges"
],
"fields": [
{
"fieldname": "tc_name",
"fieldtype": "Link",
"label": "Terms and Conditions",
"options": "Terms and Conditions"
},
{
"fieldname": "payment_terms_template",
"fieldtype": "Link",
"label": "Payment Terms Template",
"options": "Payment Terms Template"
},
{
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"label": "Taxes and Charges",
"options": "Sales Taxes and Charges Template"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2022-08-29 14:04:11.402701",
"modified_by": "Administrator",
"module": "MSP",
"name": "Auto Invoice Generator Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -0,0 +1,8 @@
# Copyright (c) 2022, itsdave GmbH and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class AutoInvoiceGeneratorSettings(Document):
pass

View File

@ -0,0 +1,8 @@
# Copyright (c) 2022, itsdave GmbH and Contributors
# See license.txt
# import frappe
import unittest
class TestAutoInvoiceGeneratorSettings(unittest.TestCase):
pass