FEAT: US Regional Module with IRS 1099 reporting

This commit is contained in:
Tyler Matteson 2019-01-17 14:04:01 -05:00
parent 38703080c9
commit 53a6492f29
8 changed files with 292 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,47 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.query_reports["IRS 1099"] = {
"filters": [
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company"),
"reqd": 1,
"width": 80,
},
{
"fieldname":"fiscal_year",
"label": __("Fiscal Year"),
"fieldtype": "Link",
"options": "Fiscal Year",
"default": frappe.defaults.get_user_default("fiscal_year"),
"reqd": 1,
"width": 80,
},
{
"fieldname":"supplier_group",
"label": __("Supplier Group"),
"fieldtype": "Link",
"options": "Supplier Group",
"default": "",
"reqd": 0,
"width": 80
},
],
onload: function(query_report) {
query_report.page.add_inner_button(__("Print IRS 1099 Forms"), () => {
build_1099_print(query_report);
});
}
};
function build_1099_print(query_report){
let filters = JSON.stringify(query_report.get_values());
let w = window.open('/api/method/erpnext.regional.report.irs_1099.irs_1099.irs_1099_print?' +
'&filters=' + encodeURIComponent(filters));
// w.print();
}

View File

@ -0,0 +1,29 @@
{
"add_total_row": 0,
"color": "#c0392b",
"creation": "2018-09-10 00:00:00",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"icon": "fa fa-star",
"idx": 0,
"is_standard": "Yes",
"letter_head": "",
"modified": "2019-01-17 08:30:41.863572",
"modified_by": "Administrator",
"module": "Regional",
"name": "IRS 1099",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Supplier",
"report_name": "IRS 1099",
"report_type": "Script Report",
"roles": [
{
"role": "System Manager"
},
{
"role": "Accounts Manager"
}
]
}

View File

@ -0,0 +1,151 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
import json
from frappe import _, _dict
from frappe.utils import nowdate
from frappe.utils.data import fmt_money
from erpnext.accounts.utils import get_fiscal_year
from PyPDF2 import PdfFileWriter
from frappe.utils.pdf import get_pdf
from frappe.utils.print_format import read_multi_pdf
from frappe.utils.jinja import render_template
def execute(filters=None):
filters = filters if isinstance(filters, _dict) else _dict(filters)
if not filters:
filters.setdefault('fiscal_year', get_fiscal_year(nowdate())[0])
filters.setdefault('company', frappe.db.get_default("company"))
data = []
columns = get_columns()
data = frappe.db.sql("""
SELECT
s.supplier_group as "supplier_group",
gl.party AS "supplier",
s.tax_id as "tax_id",
SUM(gl.debit) AS "payments"
FROM
`tabGL Entry` gl INNER JOIN `tabSupplier` s
WHERE
s.name = gl.party
AND s.irs_1099 = 1
AND gl.fiscal_year = %(fiscal_year)s
AND gl.party_type = "Supplier"
GROUP BY
gl.party
ORDER BY
gl.party DESC""", {"fiscal_year": filters.fiscal_year,
"supplier_group": filters.supplier_group,
"company": filters.company}, as_dict=True)
return columns, data
def get_columns():
return [
{
"fieldname": "supplier_group",
"label": _("Supplier Group"),
"fieldtype": "Link",
"options": "Supplier Group",
"width": 200
},
{
"fieldname": "supplier",
"label": _("Supplier"),
"fieldtype": "Link",
"options": "Supplier",
"width": 200
},
{
"fieldname": "tax_id",
"label": _("Tax ID"),
"fieldtype": "Data",
"width": 120
},
{
"fieldname": "payments",
"label": _("Total Payments"),
"fieldtype": "Currency",
"width": 120
}
]
@frappe.whitelist()
def irs_1099_print(filters):
if not filters:
frappe._dict({
"company": frappe.db.get_default("Company"),
"fiscal_year": frappe.db.get_default("fiscal_year")})
else:
filters = frappe._dict(json.loads(filters))
company_address = get_payer_address_html(filters.company)
company_tin = frappe.db.get_value("Company", filters.company, "tax_id")
columns, data = execute(filters)
template = frappe.get_doc("Print Format", "IRS 1099 Form").html
output = PdfFileWriter()
for row in data:
row["company"] = filters.company
row["company_tin"] = company_tin
row["payer_street_address"] = company_address
row["recipient_street_address"], row["recipient_city_state"] = get_street_address_html("Supplier", row.supplier)
row["payments"] = fmt_money(row["payments"], precision=0, currency="USD")
frappe._dict(row)
print(row)
pdf = get_pdf(render_template(template, row), output=output if output else None)
print(pdf)
frappe.local.response.filename = filters.fiscal_year + " " + filters.company + " IRS 1099 Forms"
frappe.local.response.filecontent = read_multi_pdf(output)
frappe.local.response.type = "download"
def get_payer_address_html(company):
address_list = frappe.db.sql("""
SELECT
name
FROM
tabAddress
WHERE
is_your_company_address = 1
ORDER BY
address_type="Postal" DESC, address_type="Billing" DESC
LIMIT 1
""", {"company": company}, as_dict=True)
if address_list:
company_address = address_list[0]["name"]
return frappe.get_doc("Address", company_address).get_display()
else:
return ""
def get_street_address_html(party_type, party):
address_list = frappe.db.sql("""
SELECT
link.parent
FROM `tabDynamic Link` link, `tabAddress` address
WHERE link.parenttype = "Address"
AND link.link_name = %(party)s
ORDER BY address.address_type="Postal" DESC,
address.address_type="Billing" DESC
LIMIT 1
""", {"party": party}, as_dict=True)
if address_list:
supplier_address = address_list[0]["parent"]
doc = frappe.get_doc("Address", supplier_address)
if doc.address_line2:
street = doc.address_line1 + "<br>\n" + doc.address_line2 + "<br>\n"
else:
street = doc.address_line1 + "<br>\n"
city = doc.city + ", " if doc.city else ""
city = city + doc.state + " " if doc.state else city
city = city + doc.pincode if doc.pincode else city
city += "<br>\n"
return street, city
else:
return "", ""

View File

@ -0,0 +1,42 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
def setup(company=None, patch=True):
make_custom_fields()
add_print_formats()
update_address_template()
def make_custom_fields():
custom_fields = {
'Supplier': [
dict(fieldname='irs_1099', fieldtype='Check', insert_after='tax_id',
label='Is IRS 1099 reporting required for supplier?')
]
}
create_custom_fields(custom_fields)
def add_print_formats():
frappe.reload_doc("regional", "print_format", "irs_1099_form")
frappe.db.sql(""" update `tabPrint Format` set disabled = 0 where
name in('IRS 1099 Form') """)
def update_address_template():
html = """{{ address_line1 }}<br>
{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}
{{ city }}, {% if state %}{{ state }}{% endif -%}{% if pincode %} {{ pincode }}<br>{% endif -%}
{% if country != "United States" %}{{ country|upper }}{% endif -%}
"""
address_template = frappe.db.get_value('Address Template', 'United States')
if address_template:
frappe.db.set_value('Address Template', 'United States', 'template', html)
else:
frappe.get_doc(dict(doctype='Address Template', country='United States', template=html)).insert()