# coding=utf-8 from __future__ import unicode_literals import os import json import zipfile from six import BytesIO from unittest import TestCase import frappe from frappe.utils import getdate, today, now_datetime, cstr from frappe.test_runner import make_test_objects from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts from erpnext.regional.report.datev.datev import validate from erpnext.regional.report.datev.datev import get_transactions from erpnext.regional.report.datev.datev import get_customers from erpnext.regional.report.datev.datev import get_suppliers from erpnext.regional.report.datev.datev import get_account_names from erpnext.regional.report.datev.datev import get_datev_csv from erpnext.regional.report.datev.datev import get_header from erpnext.regional.report.datev.datev import download_datev_csv from erpnext.regional.report.datev.datev_constants import DataCategory from erpnext.regional.report.datev.datev_constants import Transactions from erpnext.regional.report.datev.datev_constants import DebtorsCreditors from erpnext.regional.report.datev.datev_constants import AccountNames from erpnext.regional.report.datev.datev_constants import QUERY_REPORT_COLUMNS def make_company(company_name, abbr): if not frappe.db.exists("Company", company_name): company = frappe.get_doc({ "doctype": "Company", "company_name": company_name, "abbr": abbr, "default_currency": "EUR", "country": "Germany", "create_chart_of_accounts_based_on": "Standard Template", "chart_of_accounts": "SKR04 mit Kontonummern" }) company.insert() else: company = frappe.get_doc("Company", company_name) # indempotent company.create_default_warehouses() if not frappe.db.get_value("Cost Center", {"is_group": 0, "company": company.name}): company.create_default_cost_center() company.save() return company def setup_fiscal_year(): fiscal_year = None year = cstr(now_datetime().year) if not frappe.db.get_value("Fiscal Year", {"year": year}, "name"): try: fiscal_year = frappe.get_doc({ "doctype": "Fiscal Year", "year": year, "year_start_date": "{0}-01-01".format(year), "year_end_date": "{0}-12-31".format(year) }) fiscal_year.insert() except frappe.NameError: pass if fiscal_year: fiscal_year.set_as_default() def make_customer_with_account(customer_name, company): acc_name = frappe.db.get_value("Account", { "account_name": customer_name, "company": company.name }, "name") if not acc_name: acc = frappe.get_doc({ "doctype": "Account", "parent_account": "1 - Forderungen aus Lieferungen und Leistungen - _TG", "account_name": customer_name, "company": company.name, "account_type": "Receivable", "account_number": "10001" }) acc.insert() acc_name = acc.name if not frappe.db.exists("Customer", customer_name): customer = frappe.get_doc({ "doctype": "Customer", "customer_name": customer_name, "customer_type": "Company", "accounts": [{ "company": company.name, "account": acc_name }] }) customer.insert() else: customer = frappe.get_doc("Customer", customer_name) return customer def make_item(item_code, company): warehouse_name = frappe.db.get_value("Warehouse", { "warehouse_name": "Stores", "company": company.name }, "name") if not frappe.db.exists("Item", item_code): item = frappe.get_doc({ "doctype": "Item", "item_code": item_code, "item_name": item_code, "description": item_code, "item_group": "All Item Groups", "is_stock_item": 0, "is_purchase_item": 0, "is_customer_provided_item": 0, "item_defaults": [{ "default_warehouse": warehouse_name, "company": company.name }] }) item.insert() else: item = frappe.get_doc("Item", item_code) return item def make_datev_settings(company): if not frappe.db.exists("DATEV Settings", company.name): frappe.get_doc({ "doctype": "DATEV Settings", "client": company.name, "client_number": "12345", "consultant_number": "67890" }).insert() class TestDatev(TestCase): def setUp(self): self.company = make_company("_Test GmbH", "_TG") self.customer = make_customer_with_account("_Test Kunde GmbH", self.company) self.filters = { "company": self.company.name, "from_date": today(), "to_date": today() } make_datev_settings(self.company) item = make_item("_Test Item", self.company) setup_fiscal_year() warehouse = frappe.db.get_value("Item Default", { "parent": item.name, "company": self.company.name }, "default_warehouse") income_account = frappe.db.get_value("Account", { "account_number": "4200", "company": self.company.name }, "name") tax_account = frappe.db.get_value("Account", { "account_number": "3806", "company": self.company.name }, "name") si = create_sales_invoice( company=self.company.name, customer=self.customer.name, currency=self.company.default_currency, debit_to=self.customer.accounts[0].account, income_account="4200 - Erlöse - _TG", expense_account="6990 - Herstellungskosten - _TG", cost_center=self.company.cost_center, warehouse=warehouse, item=item.name, do_not_save=1 ) si.append("taxes", { "charge_type": "On Net Total", "account_head": tax_account, "description": "Umsatzsteuer 19 %", "rate": 19, "cost_center": self.company.cost_center }) si.cost_center = self.company.cost_center si.save() si.submit() def test_columns(self): def is_subset(get_data, allowed_keys): """ Validate that the dict contains only allowed keys. Params: get_data -- Function that returns a list of dicts. allowed_keys -- List of allowed keys """ data = get_data(self.filters) if data == []: # No data and, therefore, no columns is okay return True actual_set = set(data[0].keys()) # allowed set must be interpreted as unicode to match the actual set allowed_set = set({frappe.as_unicode(key) for key in allowed_keys}) return actual_set.issubset(allowed_set) self.assertTrue(is_subset(get_transactions, Transactions.COLUMNS)) self.assertTrue(is_subset(get_customers, DebtorsCreditors.COLUMNS)) self.assertTrue(is_subset(get_suppliers, DebtorsCreditors.COLUMNS)) self.assertTrue(is_subset(get_account_names, AccountNames.COLUMNS)) def test_header(self): self.assertTrue(Transactions.DATA_CATEGORY in get_header(self.filters, Transactions)) self.assertTrue(AccountNames.DATA_CATEGORY in get_header(self.filters, AccountNames)) self.assertTrue(DebtorsCreditors.DATA_CATEGORY in get_header(self.filters, DebtorsCreditors)) def test_csv(self): test_data = [{ "Umsatz (ohne Soll/Haben-Kz)": 100, "Soll/Haben-Kennzeichen": "H", "Kontonummer": "4200", "Gegenkonto (ohne BU-Schlüssel)": "10000", "Belegdatum": today(), "Buchungstext": "No remark", "Beleginfo - Art 1": "Sales Invoice", "Beleginfo - Inhalt 1": "SINV-0001" }] get_datev_csv(data=test_data, filters=self.filters, csv_class=Transactions) def test_download(self): """Assert that the returned file is a ZIP file.""" download_datev_csv(self.filters) # zipfile.is_zipfile() expects a file-like object zip_buffer = BytesIO() zip_buffer.write(frappe.response['filecontent']) self.assertTrue(zipfile.is_zipfile(zip_buffer))