mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-22 08:08:29 +00:00
Merge branch 'version-12-hotfix' into party-details-hotfix
This commit is contained in:
@@ -619,20 +619,12 @@ $.extend(erpnext.journal_entry, {
|
||||
return { filters: filters };
|
||||
},
|
||||
|
||||
reverse_journal_entry: function(frm) {
|
||||
var me = frm.doc;
|
||||
for(var i=0; i<me.accounts.length; i++) {
|
||||
me.accounts[i].credit += me.accounts[i].debit;
|
||||
me.accounts[i].debit = me.accounts[i].credit - me.accounts[i].debit;
|
||||
me.accounts[i].credit -= me.accounts[i].debit;
|
||||
me.accounts[i].credit_in_account_currency = me.accounts[i].credit;
|
||||
me.accounts[i].debit_in_account_currency = me.accounts[i].debit;
|
||||
me.accounts[i].reference_type = "Journal Entry";
|
||||
me.accounts[i].reference_name = me.name
|
||||
}
|
||||
frm.copy_doc();
|
||||
cur_frm.reload_doc();
|
||||
}
|
||||
reverse_journal_entry: function() {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.make_reverse_journal_entry",
|
||||
frm: cur_frm
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
$.extend(erpnext.journal_entry, {
|
||||
|
||||
@@ -1017,3 +1017,34 @@ def make_inter_company_journal_entry(name, voucher_type, company):
|
||||
journal_entry.posting_date = nowdate()
|
||||
journal_entry.inter_company_journal_entry_reference = name
|
||||
return journal_entry.as_dict()
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_reverse_journal_entry(source_name, target_doc=None, ignore_permissions=False):
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
|
||||
def update_accounts(source, target, source_parent):
|
||||
target.reference_type = "Journal Entry"
|
||||
target.reference_name = source_parent.name
|
||||
|
||||
doclist = get_mapped_doc("Journal Entry", source_name, {
|
||||
"Journal Entry": {
|
||||
"doctype": "Journal Entry",
|
||||
"validation": {
|
||||
"docstatus": ["=", 1]
|
||||
}
|
||||
},
|
||||
"Journal Entry Account": {
|
||||
"doctype": "Journal Entry Account",
|
||||
"field_map": {
|
||||
"account_currency": "account_currency",
|
||||
"exchange_rate": "exchange_rate",
|
||||
"debit_in_account_currency": "credit_in_account_currency",
|
||||
"debit": "credit",
|
||||
"credit_in_account_currency": "debit_in_account_currency",
|
||||
"credit": "debit",
|
||||
},
|
||||
"postprocess": update_accounts,
|
||||
},
|
||||
}, target_doc, ignore_permissions=ignore_permissions)
|
||||
|
||||
return doclist
|
||||
@@ -139,6 +139,49 @@ class TestJournalEntry(unittest.TestCase):
|
||||
|
||||
self.assertFalse(gle)
|
||||
|
||||
def test_reverse_journal_entry(self):
|
||||
from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
|
||||
jv = make_journal_entry("_Test Bank USD - _TC",
|
||||
"Sales - _TC", 100, exchange_rate=50, save=False)
|
||||
|
||||
jv.get("accounts")[1].credit_in_account_currency = 5000
|
||||
jv.get("accounts")[1].exchange_rate = 1
|
||||
jv.submit()
|
||||
|
||||
rjv = make_reverse_journal_entry(jv.name)
|
||||
rjv.posting_date = nowdate()
|
||||
rjv.submit()
|
||||
|
||||
|
||||
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
||||
debit_in_account_currency, credit_in_account_currency
|
||||
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
|
||||
order by account asc""", rjv.name, as_dict=1)
|
||||
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
|
||||
expected_values = {
|
||||
"_Test Bank USD - _TC": {
|
||||
"account_currency": "USD",
|
||||
"debit": 0,
|
||||
"debit_in_account_currency": 0,
|
||||
"credit": 5000,
|
||||
"credit_in_account_currency": 100,
|
||||
},
|
||||
"Sales - _TC": {
|
||||
"account_currency": "INR",
|
||||
"debit": 5000,
|
||||
"debit_in_account_currency": 5000,
|
||||
"credit": 0,
|
||||
"credit_in_account_currency": 0,
|
||||
}
|
||||
}
|
||||
|
||||
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEqual(expected_values[gle.account][field], gle[field])
|
||||
|
||||
def test_disallow_change_in_account_currency_for_a_party(self):
|
||||
# create jv in USD
|
||||
jv = make_journal_entry("_Test Bank USD - _TC",
|
||||
|
||||
@@ -290,6 +290,7 @@ class PayrollEntry(Document):
|
||||
"account": default_payroll_payable_account,
|
||||
"credit_in_account_currency": flt(payable_amount, precision),
|
||||
"party_type": '',
|
||||
"cost_center": self.cost_center
|
||||
})
|
||||
|
||||
journal_entry.set("accounts", accounts)
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Job Card', {
|
||||
setup: function(frm) {
|
||||
frm.set_query('operation', function() {
|
||||
return {
|
||||
query: 'erpnext.manufacturing.doctype.job_card.job_card.get_operations',
|
||||
filters: {
|
||||
'work_order': frm.doc.work_order
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
|
||||
if(frm.doc.docstatus == 0) {
|
||||
@@ -24,12 +35,60 @@ frappe.ui.form.on('Job Card', {
|
||||
}
|
||||
}
|
||||
|
||||
frm.trigger("toggle_operation_number");
|
||||
|
||||
if (frm.doc.docstatus == 0 && (frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
|
||||
&& (!frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
|
||||
&& (frm.doc.items || !frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
|
||||
frm.trigger("prepare_timer_buttons");
|
||||
}
|
||||
},
|
||||
|
||||
operation: function(frm) {
|
||||
frm.trigger("toggle_operation_number");
|
||||
|
||||
if (frm.doc.operation && frm.doc.work_order) {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.job_card.job_card.get_operation_details",
|
||||
args: {
|
||||
"work_order":frm.doc.work_order,
|
||||
"operation":frm.doc.operation
|
||||
},
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
if (r.message.length == 1) {
|
||||
frm.set_value("operation_id", r.message[0].name);
|
||||
} else {
|
||||
let args = [];
|
||||
|
||||
r.message.forEach((row) => {
|
||||
args.push({ "label": row.idx, "value": row.name });
|
||||
});
|
||||
|
||||
let description = __("Operation {0} added multiple times in the work order {1}",
|
||||
[frm.doc.operation, frm.doc.work_order]);
|
||||
|
||||
frm.set_df_property("operation_row_number", "options", args);
|
||||
frm.set_df_property("operation_row_number", "description", description);
|
||||
}
|
||||
|
||||
frm.trigger("toggle_operation_number");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
operation_row_number(frm) {
|
||||
if (frm.doc.operation_row_number) {
|
||||
frm.set_value("operation_id", frm.doc.operation_row_number);
|
||||
}
|
||||
},
|
||||
|
||||
toggle_operation_number(frm) {
|
||||
frm.toggle_display("operation_row_number", !frm.doc.operation_id && frm.doc.operation);
|
||||
frm.toggle_reqd("operation_row_number", !frm.doc.operation_id && frm.doc.operation);
|
||||
},
|
||||
|
||||
prepare_timer_buttons: function(frm) {
|
||||
frm.trigger("make_dashboard");
|
||||
if (!frm.doc.job_started) {
|
||||
@@ -39,9 +98,9 @@ frappe.ui.form.on('Job Card', {
|
||||
fieldname: 'employee'}, d => {
|
||||
if (d.employee) {
|
||||
frm.set_value("employee", d.employee);
|
||||
} else {
|
||||
frm.events.start_job(frm);
|
||||
}
|
||||
|
||||
frm.events.start_job(frm);
|
||||
}, __("Enter Value"), __("Start"));
|
||||
} else {
|
||||
frm.events.start_job(frm);
|
||||
@@ -86,9 +145,7 @@ frappe.ui.form.on('Job Card', {
|
||||
frm.set_value('current_time' , 0);
|
||||
}
|
||||
|
||||
frm.save("Save", () => {}, "", () => {
|
||||
frm.doc.time_logs.pop(-1);
|
||||
});
|
||||
frm.save();
|
||||
},
|
||||
|
||||
complete_job: function(frm, completed_time, completed_qty) {
|
||||
@@ -120,6 +177,8 @@ frappe.ui.form.on('Job Card', {
|
||||
employee: function(frm) {
|
||||
if (frm.doc.job_started && !frm.doc.current_time) {
|
||||
frm.trigger("reset_timer");
|
||||
} else {
|
||||
frm.events.start_job(frm);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"bom_no",
|
||||
"workstation",
|
||||
"operation",
|
||||
"operation_row_number",
|
||||
"column_break_4",
|
||||
"posting_date",
|
||||
"company",
|
||||
@@ -287,10 +288,15 @@
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "operation_row_number",
|
||||
"fieldtype": "Select",
|
||||
"label": "Operation Row Number"
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"modified": "2020-03-27 13:36:35.417502",
|
||||
"modified": "2020-08-24 15:21:21.398267",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Job Card",
|
||||
@@ -342,7 +348,6 @@
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "operation",
|
||||
|
||||
@@ -9,10 +9,13 @@ from frappe.utils import flt, time_diff_in_hours, get_datetime, time_diff, get_l
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe.model.document import Document
|
||||
|
||||
class OperationMismatchError(frappe.ValidationError): pass
|
||||
|
||||
class JobCard(Document):
|
||||
def validate(self):
|
||||
self.validate_time_logs()
|
||||
self.set_status()
|
||||
self.validate_operation_id()
|
||||
|
||||
def validate_time_logs(self):
|
||||
self.total_completed_qty = 0.0
|
||||
@@ -107,11 +110,10 @@ class JobCard(Document):
|
||||
for_quantity, time_in_mins = 0, 0
|
||||
from_time_list, to_time_list = [], []
|
||||
|
||||
field = "operation_id" if self.operation_id else "operation"
|
||||
field = "operation_id"
|
||||
data = frappe.get_all('Job Card',
|
||||
fields = ["sum(total_time_in_mins) as time_in_mins", "sum(total_completed_qty) as completed_qty"],
|
||||
filters = {"docstatus": 1, "work_order": self.work_order,
|
||||
"workstation": self.workstation, field: self.get(field)})
|
||||
filters = {"docstatus": 1, "work_order": self.work_order, field: self.get(field)})
|
||||
|
||||
if data and len(data) > 0:
|
||||
for_quantity = data[0].completed_qty
|
||||
@@ -124,14 +126,13 @@ class JobCard(Document):
|
||||
FROM `tabJob Card` jc, `tabJob Card Time Log` jctl
|
||||
WHERE
|
||||
jctl.parent = jc.name and jc.work_order = %s
|
||||
and jc.workstation = %s and jc.{0} = %s and jc.docstatus = 1
|
||||
""".format(field), (self.work_order, self.workstation, self.get(field)), as_dict=1)
|
||||
and jc.{0} = %s and jc.docstatus = 1
|
||||
""".format(field), (self.work_order, self.get(field)), as_dict=1)
|
||||
|
||||
wo = frappe.get_doc('Work Order', self.work_order)
|
||||
|
||||
work_order_field = "name" if field == "operation_id" else field
|
||||
for data in wo.operations:
|
||||
if data.get(work_order_field) == self.get(field):
|
||||
if data.get("name") == self.get(field):
|
||||
data.completed_qty = for_quantity
|
||||
data.actual_operation_time = time_in_mins
|
||||
data.actual_start_time = time_data[0].start_time if time_data else None
|
||||
@@ -204,6 +205,37 @@ class JobCard(Document):
|
||||
if update_status:
|
||||
self.db_set('status', self.status)
|
||||
|
||||
def validate_operation_id(self):
|
||||
if (self.get("operation_id") and self.get("operation_row_number") and self.operation and self.work_order and
|
||||
frappe.get_cached_value("Work Order Operation", self.operation_row_number, "name") != self.operation_id):
|
||||
work_order = frappe.bold(get_link_to_form("Work Order", self.work_order))
|
||||
frappe.throw(_("Operation {0} does not belong to the work order {1}")
|
||||
.format(frappe.bold(self.operation), work_order), OperationMismatchError)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_operation_details(work_order, operation):
|
||||
if work_order and operation:
|
||||
return frappe.get_all("Work Order Operation", fields = ["name", "idx"],
|
||||
filters = {
|
||||
"parent": work_order,
|
||||
"operation": operation
|
||||
}
|
||||
)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_operations(doctype, txt, searchfield, start, page_len, filters):
|
||||
if filters.get("work_order"):
|
||||
args = {"parent": filters.get("work_order")}
|
||||
if txt:
|
||||
args["operation"] = ("like", "%{0}%".format(txt))
|
||||
|
||||
return frappe.get_all("Work Order Operation",
|
||||
filters = args,
|
||||
fields = ["distinct operation as operation"],
|
||||
limit_start = start,
|
||||
limit_page_length = page_len,
|
||||
order_by="idx asc", as_list=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_material_request(source_name, target_doc=None):
|
||||
def update_item(obj, target, source_parent):
|
||||
|
||||
@@ -4,6 +4,64 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
import frappe
|
||||
from frappe.utils import random_string
|
||||
from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.manufacturing.doctype.job_card.job_card import OperationMismatchError
|
||||
|
||||
class TestJobCard(unittest.TestCase):
|
||||
pass
|
||||
def test_job_card(self):
|
||||
data = frappe.get_cached_value('BOM',
|
||||
{'docstatus': 1, 'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
|
||||
|
||||
if data:
|
||||
bom, bom_item = data
|
||||
|
||||
work_order = make_wo_order_test_record(item=bom_item, qty=1, bom_no=bom)
|
||||
|
||||
job_cards = frappe.get_all('Job Card',
|
||||
filters = {'work_order': work_order.name}, fields = ["operation_id", "name"])
|
||||
|
||||
if job_cards:
|
||||
job_card = job_cards[0]
|
||||
frappe.db.set_value("Job Card", job_card.name, "operation_row_number", job_card.operation_id)
|
||||
|
||||
doc = frappe.get_doc("Job Card", job_card.name)
|
||||
doc.operation_id = "Test Data"
|
||||
self.assertRaises(OperationMismatchError, doc.save)
|
||||
|
||||
def test_job_card_with_different_work_station(self):
|
||||
data = frappe.get_cached_value('BOM',
|
||||
{'docstatus': 1, 'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
|
||||
|
||||
if data:
|
||||
bom, bom_item = data
|
||||
|
||||
work_order = make_wo_order_test_record(item=bom_item, qty=1, bom_no=bom)
|
||||
|
||||
job_card = frappe.get_all('Job Card',
|
||||
filters = {'work_order': work_order.name},
|
||||
fields = ["operation_id", "workstation", "name", "for_quantity"])[0]
|
||||
|
||||
if job_card:
|
||||
workstation = frappe.db.get_value("Workstation",
|
||||
{"name": ("not in", [job_card.workstation])}, "name")
|
||||
|
||||
if not workstation or job_card.workstation == workstation:
|
||||
workstation = make_workstation(workstation_name=random_string(5)).name
|
||||
|
||||
doc = frappe.get_doc("Job Card", job_card.name)
|
||||
doc.workstation = workstation
|
||||
doc.append("time_logs", {
|
||||
"from_time": "2009-01-01 12:06:25",
|
||||
"to_time": "2009-01-01 12:37:25",
|
||||
"time_in_mins": "31.00002",
|
||||
"completed_qty": job_card.for_quantity
|
||||
})
|
||||
doc.submit()
|
||||
|
||||
completed_qty = frappe.db.get_value("Work Order Operation", job_card.operation_id, "completed_qty")
|
||||
self.assertEqual(completed_qty, job_card.for_quantity)
|
||||
|
||||
doc.cancel()
|
||||
@@ -20,3 +20,18 @@ class TestWorkstation(unittest.TestCase):
|
||||
"_Test Workstation 1", "Operation 1", "2013-02-02 05:00:00", "2013-02-02 20:00:00")
|
||||
self.assertRaises(WorkstationHolidayError, check_if_within_operating_hours,
|
||||
"_Test Workstation 1", "Operation 1", "2013-02-01 10:00:00", "2013-02-02 20:00:00")
|
||||
|
||||
def make_workstation(**args):
|
||||
args = frappe._dict(args)
|
||||
|
||||
try:
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Workstation",
|
||||
"workstation_name": args.workstation_name
|
||||
})
|
||||
|
||||
doc.insert()
|
||||
|
||||
return doc
|
||||
except frappe.DuplicateEntryError:
|
||||
return frappe.get_doc("Workstation", args.workstation_name)
|
||||
@@ -508,7 +508,7 @@ erpnext.buying.get_items_from_product_bundle = function(frm) {
|
||||
var d = frm.add_child("items");
|
||||
var item = r.message[i];
|
||||
for ( var key in item) {
|
||||
if ( !is_null(item[key]) ) {
|
||||
if ( !is_null(item[key]) && key !== "doctype" ) {
|
||||
d[key] = item[key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,5 +46,28 @@ frappe.query_reports["HSN-wise-summary of outward supplies"] = {
|
||||
],
|
||||
onload: (report) => {
|
||||
fetch_gstins(report);
|
||||
|
||||
report.page.add_inner_button(__("Download JSON"), function () {
|
||||
var filters = report.get_values();
|
||||
|
||||
frappe.call({
|
||||
method: 'erpnext.regional.report.hsn_wise_summary_of_outward_supplies.hsn_wise_summary_of_outward_supplies.get_json',
|
||||
args: {
|
||||
data: report.data,
|
||||
report_name: report.report_name,
|
||||
filters: filters
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
const args = {
|
||||
cmd: 'erpnext.regional.report.hsn_wise_summary_of_outward_supplies.hsn_wise_summary_of_outward_supplies.download_json_file',
|
||||
data: r.message.data,
|
||||
report_name: r.message.report_name
|
||||
};
|
||||
open_url_post(frappe.request.url, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.utils import flt, getdate, cstr
|
||||
from frappe.model.meta import get_field_precision
|
||||
from frappe.utils.xlsxutils import handle_html
|
||||
from six import iteritems
|
||||
import json
|
||||
from erpnext.regional.india.utils import get_gst_accounts
|
||||
from erpnext.regional.report.gstr_1.gstr_1 import get_company_gstin_number
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
@@ -141,7 +143,7 @@ def get_tax_accounts(item_list, columns, company_currency, doctype="Sales Invoic
|
||||
|
||||
tax_details = frappe.db.sql("""
|
||||
select
|
||||
parent, description, item_wise_tax_detail,
|
||||
parent, account_head, item_wise_tax_detail,
|
||||
base_tax_amount_after_discount_amount
|
||||
from `tab%s`
|
||||
where
|
||||
@@ -153,11 +155,11 @@ def get_tax_accounts(item_list, columns, company_currency, doctype="Sales Invoic
|
||||
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
|
||||
tuple([doctype] + list(invoice_item_row)))
|
||||
|
||||
for parent, description, item_wise_tax_detail, tax_amount in tax_details:
|
||||
description = handle_html(description)
|
||||
if description not in tax_columns and tax_amount:
|
||||
for parent, account_head, item_wise_tax_detail, tax_amount in tax_details:
|
||||
|
||||
if account_head not in tax_columns and tax_amount:
|
||||
# as description is text editor earlier and markup can break the column convention in reports
|
||||
tax_columns.append(description)
|
||||
tax_columns.append(account_head)
|
||||
|
||||
if item_wise_tax_detail:
|
||||
try:
|
||||
@@ -175,17 +177,17 @@ def get_tax_accounts(item_list, columns, company_currency, doctype="Sales Invoic
|
||||
for d in item_row_map.get(parent, {}).get(item_code, []):
|
||||
item_tax_amount = tax_amount
|
||||
if item_tax_amount:
|
||||
itemised_tax.setdefault((parent, item_code), {})[description] = frappe._dict({
|
||||
itemised_tax.setdefault((parent, item_code), {})[account_head] = frappe._dict({
|
||||
"tax_amount": flt(item_tax_amount, tax_amount_precision)
|
||||
})
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
tax_columns.sort()
|
||||
for desc in tax_columns:
|
||||
for account_head in tax_columns:
|
||||
columns.append({
|
||||
"label": desc,
|
||||
"fieldname": frappe.scrub(desc),
|
||||
"label": account_head,
|
||||
"fieldname": frappe.scrub(account_head),
|
||||
"fieldtype": "Float",
|
||||
"width": 110
|
||||
})
|
||||
@@ -212,3 +214,76 @@ def get_merged_data(columns, data):
|
||||
|
||||
return result
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_json(filters, report_name, data):
|
||||
filters = json.loads(filters)
|
||||
report_data = json.loads(data)
|
||||
gstin = filters.get('company_gstin') or get_company_gstin_number(filters["company"])
|
||||
|
||||
if not filters.get('from_date') or not filters.get('to_date'):
|
||||
frappe.throw(_("Please enter From Date and To Date to generate JSON"))
|
||||
|
||||
fp = "%02d%s" % (getdate(filters["to_date"]).month, getdate(filters["to_date"]).year)
|
||||
|
||||
gst_json = {"version": "GST2.3.4",
|
||||
"hash": "hash", "gstin": gstin, "fp": fp}
|
||||
|
||||
gst_json["hsn"] = {
|
||||
"data": get_hsn_wise_json_data(filters, report_data)
|
||||
}
|
||||
|
||||
return {
|
||||
'report_name': report_name,
|
||||
'data': gst_json
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_json_file():
|
||||
'''download json content in a file'''
|
||||
data = frappe._dict(frappe.local.form_dict)
|
||||
frappe.response['filename'] = frappe.scrub("{0}".format(data['report_name'])) + '.json'
|
||||
frappe.response['filecontent'] = data['data']
|
||||
frappe.response['content_type'] = 'application/json'
|
||||
frappe.response['type'] = 'download'
|
||||
|
||||
def get_hsn_wise_json_data(filters, report_data):
|
||||
|
||||
filters = frappe._dict(filters)
|
||||
gst_accounts = get_gst_accounts(filters.company)
|
||||
data = []
|
||||
count = 1
|
||||
|
||||
for hsn in report_data:
|
||||
row = {
|
||||
"num": count,
|
||||
"hsn_sc": hsn.get("gst_hsn_code"),
|
||||
"desc": hsn.get("description"),
|
||||
"uqc": hsn.get("stock_uom").upper(),
|
||||
"qty": hsn.get("stock_qty"),
|
||||
"val": flt(hsn.get("total_amount"), 2),
|
||||
"txval": flt(hsn.get("taxable_amount", 2)),
|
||||
"iamt": 0.0,
|
||||
"camt": 0.0,
|
||||
"samt": 0.0,
|
||||
"csamt": 0.0
|
||||
|
||||
}
|
||||
|
||||
for account in gst_accounts.get('igst_account'):
|
||||
row['iamt'] += flt(hsn.get(frappe.scrub(cstr(account)), 0.0), 2)
|
||||
|
||||
for account in gst_accounts.get('cgst_account'):
|
||||
row['camt'] += flt(hsn.get(frappe.scrub(cstr(account)), 0.0), 2)
|
||||
|
||||
for account in gst_accounts.get('sgst_account'):
|
||||
row['samt'] += flt(hsn.get(frappe.scrub(cstr(account)), 0.0), 2)
|
||||
|
||||
for account in gst_accounts.get('cess_account'):
|
||||
row['csamt'] += flt(hsn.get(frappe.scrub(cstr(account)), 0.0), 2)
|
||||
|
||||
data.append(row)
|
||||
count +=1
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
@@ -262,9 +262,17 @@ def _make_customer(source_name, ignore_permissions=False):
|
||||
return customer
|
||||
else:
|
||||
raise
|
||||
except frappe.MandatoryError:
|
||||
except frappe.MandatoryError as e:
|
||||
mandatory_fields = e.args[0].split(':')[1].split(',')
|
||||
mandatory_fields = [customer.meta.get_label(field.strip()) for field in mandatory_fields]
|
||||
|
||||
frappe.local.message_log = []
|
||||
frappe.throw(_("Please create Customer from Lead {0}").format(lead_name))
|
||||
lead_link = frappe.utils.get_link_to_form("Lead", lead_name)
|
||||
message = _("Could not auto create Customer due to the following missing mandatory field(s):") + "<br>"
|
||||
message += "<br><ul><li>" + "</li><li>".join(mandatory_fields) + "</li></ul>"
|
||||
message += _("Please create Customer from Lead {0}.").format(lead_link)
|
||||
|
||||
frappe.throw(message, title=_("Mandatory Missing"))
|
||||
else:
|
||||
return customer_name
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user