Compare commits

...

40 Commits

Author SHA1 Message Date
Nabin Hait
13bd538aca Merge branch 'develop' 2015-06-14 22:04:51 +05:30
Nabin Hait
d72a24965b bumped to version 5.0.23 2015-06-14 22:34:51 +06:00
Nabin Hait
dc633fe360 Merge pull request #3470 from nabinhait/develop
Performance upgrade in reports and indexing
2015-06-14 22:01:30 +05:30
Nabin Hait
39046d663d [patch] Add index on Account and GL Entry table 2015-06-14 20:59:28 +05:30
Nabin Hait
6b01abe9ad [report][performance] Speed increased by approx 10 times in Trial Balance, General Ledger, AR/AP, Balance Sheet and P&L Statement 2015-06-14 20:59:28 +05:30
Nabin Hait
87edd86854 Merge branch 'develop' 2015-06-12 18:06:21 +05:30
Nabin Hait
e37dd77923 bumped to version 5.0.22 2015-06-12 18:36:21 +06:00
Nabin Hait
e4f689184f Merge pull request #3459 from neilLasrado/po
Multiple Fixes.
2015-06-12 17:55:23 +05:30
Nabin Hait
85f825e98c Merge pull request #3463 from nabinhait/develop
multiple issues
2015-06-12 17:48:54 +05:30
Nabin Hait
89592c5180 Load tasks in project for printing purpose 2015-06-12 17:37:28 +05:30
Neil Trini Lasrado
587bd144d5 Added Customers Not Buying Since Long Time against Sales Invoice 2015-06-11 18:36:52 +05:30
Neil Trini Lasrado
1f048b2426 Fixes in Activity Cost 2015-06-11 18:36:52 +05:30
Neil Trini Lasrado
1792ff3be7 Validation added in Purchase Invoice to check if Supplier Invoice Date is greater than Posting Date
Check Supplier Invoice Number Uniqueness setting added to Accounts Settings
Validation added in Purchase Invoice to check Supplier Invoice Number Uniqueness if Check Supplier Invoice Number Uniqueness is enabled in Accounts Settings
2015-06-11 18:36:52 +05:30
Neil Trini Lasrado
fc595064e0 validation added to prevent Delivery Date in Porduction Order to be lesser than Planned Start Date 2015-06-11 18:36:52 +05:30
Nabin Hait
804b4acb9b [fix] Issue fixed in C-Form related to field renaming 2015-06-11 16:56:36 +05:30
Nabin Hait
5c7557914b Removed BOM No from mandatory from Stock Entry against Production Order 2015-06-11 16:50:35 +05:30
Nabin Hait
381a9377d9 Merge branch 'develop' 2015-06-11 16:14:48 +05:30
Nabin Hait
9bdd1aa1ed bumped to version 5.0.21 2015-06-11 16:44:48 +06:00
Nabin Hait
d0df28bfa0 Merge pull request #3458 from nabinhait/develop
[fix] load tasks in project via __setup__ instead of onload function, to return tasks via get_doc
2015-06-11 16:12:05 +05:30
Nabin Hait
1966225450 [fix] load tasks in project via __setup__ instead of onload function, to return tasks via get_doc 2015-06-11 15:31:47 +05:30
Nabin Hait
4cee27eec0 Merge pull request #3446 from anandpdoshi/anand-june-9
POS - search by Item Group
2015-06-10 18:42:14 +05:30
Nabin Hait
c7d4eaee79 Merge pull request #3442 from nabinhait/develop
fixes in stock entry and report
2015-06-10 18:40:42 +05:30
Nabin Hait
43c1a9b502 [fix] Quote url for item image in product listing page 2015-06-10 18:23:17 +05:30
Nabin Hait
b937fac3ce [report] Warehouse column added in 'Ordered Items to be Delivered' report 2015-06-10 18:21:57 +05:30
Nabin Hait
53d94996ad [fix] Query for Against Journal Entry 2015-06-10 18:20:18 +05:30
Anand Doshi
26f6752c1e POS - search by Item Group 2015-06-09 16:33:46 -04:00
Nabin Hait
bb429745c0 [fix] Blank option in naming series 2015-06-09 18:59:51 +05:30
Nabin Hait
909f0c38f1 [report][enhancement] Payment period based on invoice date: show party columns and filter based on party 2015-06-09 18:42:52 +05:30
Nabin Hait
a790ba05f4 [fix] Item name, description should not be overwritten on saving of stock entry 2015-06-09 18:42:52 +05:30
Nabin Hait
11fc4f85d0 Merge branch 'develop' 2015-06-09 15:56:20 +05:30
Nabin Hait
17452a1695 bumped to version 5.0.20 2015-06-09 16:26:20 +06:00
Nabin Hait
7c3d48e353 Merge pull request #3434 from neilLasrado/material-request
Status Indicators fixed in Material Request List
2015-06-09 15:47:46 +05:30
Neil Trini Lasrado
5d288e407c item variants patch removed 2015-06-09 15:46:57 +05:30
Neil Trini Lasrado
f64fae752f fixes 2015-06-09 15:46:57 +05:30
Neil Trini Lasrado
82763f052f Status Indicators fixed in Material Request List 2015-06-09 15:46:57 +05:30
Nabin Hait
bafc73568a Merge pull request #3435 from neilLasrado/barcode
Barcode added to Purchase Receipt
2015-06-09 15:44:09 +05:30
Neil Trini Lasrado
d015195617 fixes in barcode 2015-06-09 15:21:50 +05:30
Neil Trini Lasrado
b2f550ccb3 Barcode added to Purchase Receipt 2015-06-09 15:18:58 +05:30
Nabin Hait
41413af42d Merge pull request #3437 from anandpdoshi/task-close-assignment
[fix] Close assignment (ToDo) when Task status is changed to Closed
2015-06-09 15:00:06 +05:30
Anand Doshi
ec60ebde6f [fix] Close assignment (ToDo) when Task status is changed to Closed 2015-06-08 12:48:11 -04:00
38 changed files with 379 additions and 231 deletions

View File

@@ -1,2 +1,2 @@
from __future__ import unicode_literals
__version__ = '5.0.19'
__version__ = '5.0.23'

View File

@@ -35,7 +35,7 @@
"permlevel": 0,
"read_only": 1,
"reqd": 1,
"search_index": 1
"search_index": 0
},
{
"default": "0",
@@ -44,7 +44,7 @@
"label": "Is Group",
"permlevel": 0,
"precision": "",
"search_index": 1
"search_index": 0
},
{
"fieldname": "company",
@@ -57,7 +57,7 @@
"permlevel": 0,
"read_only": 1,
"reqd": 1,
"search_index": 1
"search_index": 0
},
{
"fieldname": "root_type",
@@ -147,7 +147,8 @@
"label": "Lft",
"permlevel": 0,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "rgt",
@@ -156,7 +157,8 @@
"label": "Rgt",
"permlevel": 0,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "old_parent",
@@ -171,7 +173,7 @@
"icon": "icon-money",
"idx": 1,
"in_create": 0,
"modified": "2015-05-28 14:10:40.606010",
"modified": "2015-06-14 20:57:55.471334",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",

View File

@@ -4,6 +4,13 @@
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "check_supplier_invoice_uniqueness",
"fieldtype": "Check",
"label": "Check Supplier Invoice Number Uniqueness",
"permlevel": 0,
"precision": ""
},
{
"default": "1",
"description": "If enabled, the system will post accounting entries for inventory automatically.",
@@ -43,7 +50,7 @@
"icon": "icon-cog",
"idx": 1,
"issingle": 1,
"modified": "2015-02-05 05:11:34.163902",
"modified": "2015-06-11 06:06:34.047890",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -54,7 +54,7 @@ class CForm(Document):
frappe.throw(_("Please enter atleast 1 invoice in the table"))
def set_total_invoiced_amount(self):
total = sum([flt(d.base_grand_total) for d in self.get('invoices')])
total = sum([flt(d.grand_total) for d in self.get('invoices')])
frappe.db.set(self, 'total_invoiced_amount', total)
def get_invoice_details(self, invoice_no):

View File

@@ -48,7 +48,8 @@
"fieldtype": "Dynamic Link",
"label": "Party",
"options": "party_type",
"permlevel": 0
"permlevel": 0,
"search_index": 1
},
{
"fieldname": "cost_center",
@@ -192,7 +193,7 @@
"icon": "icon-list",
"idx": 1,
"in_create": 1,
"modified": "2015-04-27 20:32:48.246818",
"modified": "2015-06-14 20:57:19.800276",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GL Entry",

View File

@@ -458,11 +458,11 @@ def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None):
if voucher_type=="Bank Entry":
account = frappe.db.get_value("Company", company, "default_bank_account")
if not account:
account = frappe.db.get_value("Account", {"company": company, "account_type": "Bank"})
account = frappe.db.get_value("Account", {"company": company, "account_type": "Bank", "is_group": 0})
elif voucher_type=="Cash Entry":
account = frappe.db.get_value("Company", company, "default_cash_account")
if not account:
account = frappe.db.get_value("Account", {"company": company, "account_type": "Cash"})
account = frappe.db.get_value("Account", {"company": company, "account_type": "Cash", "is_group": 0})
if account:
return {
@@ -538,15 +538,13 @@ def get_opening_accounts(company):
def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
if not filters.get("party"):
return []
return frappe.db.sql("""select jv.name, jv.posting_date, jv.user_remark
from `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
where jv_detail.parent = jv.name and jv_detail.account = %s and jv_detail.party = %s
where jv_detail.parent = jv.name and jv_detail.account = %s and ifnull(jv_detail.party, '') = %s
and (ifnull(jv_detail.against_invoice, '') = '' and ifnull(jv_detail.against_voucher, '') = ''
and ifnull(jv_detail.against_jv, '') = '' )
and jv.docstatus = 1 and jv.{0} like %s order by jv.name desc limit %s, %s""".format(searchfield),
(filters["account"], filters["party"], "%{0}%".format(txt), start, page_len))
(filters.get("account"), cstr(filters.get("party")), "%{0}%".format(txt), start, page_len))
@frappe.whitelist()
def get_outstanding(args):

View File

@@ -39,6 +39,7 @@ class PurchaseInvoice(BuyingController):
self.po_required()
self.pr_required()
self.validate_supplier_invoice()
self.check_active_purchase_items()
self.check_conversion_rate()
self.validate_credit_to_acc()
@@ -385,6 +386,16 @@ class PurchaseInvoice(BuyingController):
project.update_purchase_costing()
project.save()
project_list.append(d.project_name)
def validate_supplier_invoice(self):
if self.bill_date:
if self.bill_date > self.posting_date:
frappe.throw("Supplier Invoice Date cannot be greater than Posting Date")
if self.bill_no:
if cint(frappe.db.get_single_value("Accounts Settings", "check_supplier_invoice_uniqueness")):
pi = frappe.db.exists("Purchase Invoice", {"bill_no": self.bill_no, "fiscal_year": self.fiscal_year})
if pi:
frappe.throw("Supplier Invoice No exists in Purchase Invoice {0}".format(pi))
@frappe.whitelist()
def get_expense_account(doctype, txt, searchfield, start, page_len, filters):

View File

@@ -7,6 +7,7 @@ import frappe
@frappe.whitelist()
def get_items(price_list, sales_or_purchase, item=None):
condition = ""
order_by = ""
args = {"price_list": price_list}
if sales_or_purchase == "Sales":
@@ -30,16 +31,25 @@ def get_items(price_list, sales_or_purchase, item=None):
item_code[0]["barcode"] = item
return item_code
condition += " and (CONCAT(i.name, i.item_name) like %(name)s or (i.variant_of like %(name)s))"
condition += " and ((CONCAT(i.name, i.item_name) like %(name)s) or (i.variant_of like %(name)s) or (i.item_group like %(name)s))"
order_by = """if(locate(%(_name)s, i.name), locate(%(_name)s, i.name), 99999),
if(locate(%(_name)s, i.item_name), locate(%(_name)s, i.item_name), 99999),
if(locate(%(_name)s, i.variant_of), locate(%(_name)s, i.variant_of), 99999),
if(locate(%(_name)s, i.item_group), locate(%(_name)s, i.item_group), 99999),"""
args["name"] = "%%%s%%" % item
args["_name"] = item.replace("%", "")
# locate function is used to sort by closest match from the beginning of the value
return frappe.db.sql("""select i.name, i.item_name, i.image,
item_det.price_list_rate, item_det.currency
from `tabItem` i LEFT JOIN
(select item_code, price_list_rate, currency from
`tabItem Price` where price_list=%s) item_det
`tabItem Price` where price_list=%(price_list)s) item_det
ON
(item_det.item_code=i.name or item_det.item_code=i.variant_of)
where
ifnull(i.has_variants, 0) = 0 and
%s""" % ('%(price_list)s', condition), args, as_dict=1)
{condition}
order by
{order_by}
i.name""".format(condition=condition, order_by=order_by), args, as_dict=1)

View File

@@ -51,7 +51,7 @@ class ReceivablePayableReport(object):
currency_precision = get_currency_precision() or 2
dr_or_cr = "debit" if args.get("party_type") == "Customer" else "credit"
voucher_details = self.get_voucher_details()
voucher_details = self.get_voucher_details(args.get("party_type"))
future_vouchers = self.get_entries_after(self.filters.report_date, args.get("party_type"))
@@ -153,23 +153,26 @@ class ReceivablePayableReport(object):
return self.party_map
def get_voucher_details(self):
def get_voucher_details(self, party_type):
voucher_details = frappe._dict()
if party_type == "Customer":
for si in frappe.db.sql("""select name, due_date
from `tabSales Invoice` where docstatus=1""", as_dict=1):
voucher_details.setdefault(si.name, si)
for si in frappe.db.sql("""select name, due_date
from `tabSales Invoice` where docstatus=1""", as_dict=1):
voucher_details.setdefault(si.name, si)
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
from `tabPurchase Invoice` where docstatus=1""", as_dict=1):
voucher_details.setdefault(pi.name, pi)
if party_type == "Supplier":
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
from `tabPurchase Invoice` where docstatus=1""", as_dict=1):
voucher_details.setdefault(pi.name, pi)
return voucher_details
def get_gl_entries(self, party_type):
if not hasattr(self, "gl_entries"):
conditions, values = self.prepare_conditions(party_type)
self.gl_entries = frappe.db.sql("""select * from `tabGL Entry`
self.gl_entries = frappe.db.sql("""select posting_date, account, party_type, party, debit, credit,
voucher_type, voucher_no, against_voucher_type, against_voucher from `tabGL Entry`
where docstatus < 2 and party_type=%s {0} order by posting_date, party"""
.format(conditions), values, as_dict=True)
@@ -187,7 +190,7 @@ class ReceivablePayableReport(object):
if self.filters.get(party_type_field):
conditions.append("party=%s")
values.append(self.filters.get(party_type_field))
values.append(self.filters.get(party_type_field))
return " and ".join(conditions), values

View File

@@ -83,7 +83,7 @@ def get_data(company, root_type, balance_must_be, period_list, ignore_closing_en
gl_entries_by_account = get_gl_entries(company, period_list[0]["from_date"], period_list[-1]["to_date"],
accounts[0].lft, accounts[0].rgt, ignore_closing_entries=ignore_closing_entries)
calculate_values(accounts, gl_entries_by_account, period_list)
calculate_values(accounts_by_name, gl_entries_by_account, period_list)
accumulate_values_into_parents(accounts, accounts_by_name, period_list)
out = prepare_data(accounts, balance_must_be, period_list)
@@ -92,16 +92,14 @@ def get_data(company, root_type, balance_must_be, period_list, ignore_closing_en
return out
def calculate_values(accounts, gl_entries_by_account, period_list):
for d in accounts:
for name in ([d.name] + (d.collapsed_children or [])):
for entry in gl_entries_by_account.get(name, []):
for period in period_list:
entry.posting_date = getdate(entry.posting_date)
# check if posting date is within the period
if entry.posting_date <= period.to_date:
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
def calculate_values(accounts_by_name, gl_entries_by_account, period_list):
for entries in gl_entries_by_account.values():
for entry in entries:
d = accounts_by_name.get(entry.account)
for period in period_list:
# check if posting date is within the period
if entry.posting_date <= period.to_date:
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
def accumulate_values_into_parents(accounts, accounts_by_name, period_list):
@@ -159,22 +157,8 @@ def add_total_row(out, balance_must_be, period_list):
out.append({})
def get_accounts(company, root_type):
# root lft, rgt
root_account = frappe.db.sql("""select lft, rgt from `tabAccount`
where company=%s and root_type=%s and ifnull(parent_account, '') = ''
order by lft limit 1""",
(company, root_type), as_dict=True)
if not root_account:
return None
lft, rgt = root_account[0].lft, root_account[0].rgt
accounts = frappe.db.sql("""select * from `tabAccount`
where company=%(company)s and lft >= %(lft)s and rgt <= %(rgt)s order by lft""",
{ "company": company, "lft": lft, "rgt": rgt }, as_dict=True)
return accounts
return frappe.db.sql("""select name, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount`
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
def filter_accounts(accounts, depth=10):
parent_children_map = {}
@@ -196,14 +180,6 @@ def filter_accounts(accounts, depth=10):
filtered_accounts.append(child)
add_to_list(child.name, level + 1)
else:
# include all children at level lower than the depth
parent_account = accounts_by_name[parent]
parent_account["collapsed_children"] = []
for d in accounts:
if d.lft > parent_account.lft and d.rgt < parent_account.rgt:
parent_account["collapsed_children"].append(d.name)
add_to_list(None, 0)
return filtered_accounts, accounts_by_name
@@ -234,7 +210,7 @@ def get_gl_entries(company, from_date, to_date, root_lft, root_rgt, ignore_closi
if from_date:
additional_conditions.append("and posting_date >= %(from_date)s")
gl_entries = frappe.db.sql("""select * from `tabGL Entry`
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit from `tabGL Entry`
where company=%(company)s
{additional_conditions}
and posting_date <= %(to_date)s

View File

@@ -66,7 +66,7 @@ def get_gl_entries(filters):
gl_entries = frappe.db.sql("""select posting_date, account, party_type, party,
sum(ifnull(debit, 0)) as debit, sum(ifnull(credit, 0)) as credit,
voucher_type, voucher_no, cost_center, remarks, is_opening, against
voucher_type, voucher_no, cost_center, remarks, against
from `tabGL Entry`
where company=%(company)s {conditions}
{group_by_condition}
@@ -91,6 +91,9 @@ def get_conditions(filters):
if filters.get("party"):
conditions.append("party=%(party)s")
if not (filters.get("account") or filters.get("party") or filters.get("group_by_account")):
conditions.append("posting_date >=%(from_date)s")
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("GL Entry")
@@ -148,14 +151,15 @@ def initialize_gle_map(gl_entries):
def get_accountwise_gle(filters, gl_entries, gle_map):
opening, total_debit, total_credit = 0, 0, 0
from_date, to_date = getdate(filters.from_date), getdate(filters.to_date)
for gle in gl_entries:
amount = flt(gle.debit, 3) - flt(gle.credit, 3)
if gle.posting_date < getdate(filters.from_date):
if (filters.get("account") or filters.get("party") or filters.get("group_by_account")) \
and gle.posting_date < from_date:
gle_map[gle.account].opening += amount
if filters.get("account") or filters.get("party"):
opening += amount
elif gle.posting_date <= getdate(filters.to_date):
elif gle.posting_date <= to_date:
gle_map[gle.account].entries.append(gle)
gle_map[gle.account].total_debit += flt(gle.debit, 3)
gle_map[gle.account].total_credit += flt(gle.credit, 3)

View File

@@ -3,6 +3,14 @@
frappe.query_reports["Payment Period Based On Invoice Date"] = {
"filters": [
{
fieldname:"company",
label: __("Company"),
fieldtype: "Link",
options: "Company",
reqd: 1,
default: frappe.defaults.get_user_default("company")
},
{
fieldname: "from_date",
label: __("From Date"),
@@ -23,27 +31,28 @@ frappe.query_reports["Payment Period Based On Invoice Date"] = {
default: "Incoming"
},
{
fieldname:"account",
label: __("Account"),
fieldtype: "Link",
options: "Account",
get_query: function() {
"fieldname":"party_type",
"label": __("Party Type"),
"fieldtype": "Link",
"options": "DocType",
"get_query": function() {
return {
query: "erpnext.controllers.queries.get_account_list",
filters: {
"report_type": "Balance Sheet",
company: frappe.query_report.filters_by_name.company.get_value()
}
filters: {"name": ["in", ["Customer", "Supplier"]]}
}
}
},
{
fieldname:"company",
label: __("Company"),
fieldtype: "Link",
options: "Company",
reqd: 1,
default: frappe.defaults.get_user_default("company")
"fieldname":"party",
"label": __("Party"),
"fieldtype": "Dynamic Link",
"get_options": function() {
var party_type = frappe.query_report.filters_by_name.party_type.get_value();
var party = frappe.query_report.filters_by_name.party.get_value();
if(party && !party_type) {
frappe.throw(__("Please select Party Type first"));
}
return party_type;
}
},
]
}

View File

@@ -20,16 +20,16 @@ def execute(filters=None):
for d in entries:
if d.against_voucher:
against_date = d.against_voucher and invoice_posting_date_map[d.against_voucher] or ""
outstanding_amount = flt(d.debit) or -1 * flt(d.credit)
payment_amount = flt(d.debit) or -1 * flt(d.credit)
else:
against_date = d.against_invoice and invoice_posting_date_map[d.against_invoice] or ""
outstanding_amount = flt(d.credit) or -1 * flt(d.debit)
payment_amount = flt(d.credit) or -1 * flt(d.debit)
row = [d.name, d.account, d.posting_date, d.against_voucher or d.against_invoice,
row = [d.name, d.party_type, d.party, d.posting_date, d.against_voucher or d.against_invoice,
against_date, d.debit, d.credit, d.cheque_no, d.cheque_date, d.remark]
if d.against_voucher or d.against_invoice:
row += get_ageing_data(30, 60, 90, d.posting_date, against_date, outstanding_amount)
row += get_ageing_data(30, 60, 90, d.posting_date, against_date, payment_amount)
else:
row += ["", "", "", "", ""]
@@ -38,7 +38,8 @@ def execute(filters=None):
return columns, data
def get_columns():
return [_("Journal Entry") + ":Link/Journal Entry:140", _("Account") + ":Link/Account:140",
return [_("Journal Entry") + ":Link/Journal Entry:140",
_("Party Type") + ":Link/DocType:100", _("Party") + ":Dynamic Link/party_type:140",
_("Posting Date") + ":Date:100", _("Against Invoice") + ":Link/Purchase Invoice:130",
_("Against Invoice Posting Date") + ":Date:130", _("Debit") + ":Currency:120", _("Credit") + ":Currency:120",
_("Reference No") + "::100", _("Reference Date") + ":Date:100", _("Remarks") + "::150", _("Age") +":Int:40",
@@ -46,41 +47,38 @@ def get_columns():
]
def get_conditions(filters):
conditions = ""
party = None
conditions = []
if filters.get("account"):
party = filters["account"]
else:
conditions += " and company = '%s'" % frappe.db.escape(filters["company"])
if not filters.get("party_type"):
if filters.get("payment_type") == "Outgoing":
filters["party_type"] = "Supplier"
else:
filters["party_type"] = "Customer"
if filters.get("party_type"):
conditions.append("jvd.party_type=%(party_type)s")
account_type = "Receivable" if filters.get("payment_type") == "Incoming" else "Payable"
if filters.get("party"):
conditions.append("jvd.party=%(party)s")
conditions += """ and account in
(select name from tabAccount
where account_type = '{0}'
and company='{1}')""".format(account_type, frappe.db.escape(filters["company"]))
if party:
conditions += " and jvd.party = '%s'" % frappe.db.escape(party)
else:
conditions += " and ifnull(jvd.party, '') != ''"
if filters.get("company"):
conditions.append("jv.company=%(company)s")
if filters.get("from_date"):
conditions += " and jv.posting_date >= '%s'" % filters["from_date"]
conditions.append("jv.posting_date >= %(from_date)s")
if filters.get("to_date"):
conditions += " and jv.posting_date <= '%s'" % filters["to_date"]
conditions.append("jv.posting_date <= %(to_date)s")
return conditions
return "and {}".format(" and ".join(conditions)) if conditions else ""
def get_entries(filters):
conditions = get_conditions(filters)
entries = frappe.db.sql("""select jv.name, jvd.account, jv.posting_date,
entries = frappe.db.sql("""select jv.name, jvd.party_type, jvd.party, jv.posting_date,
jvd.against_voucher, jvd.against_invoice, jvd.debit, jvd.credit,
jv.cheque_no, jv.cheque_date, jv.remark
from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
where jvd.parent = jv.name and jv.docstatus=1 %s order by jv.name DESC""" %
conditions, as_dict=1, debug=1)
conditions, filters, as_dict=1)
return entries

View File

@@ -9,7 +9,7 @@ from erpnext.accounts.report.financial_statements import filter_accounts, get_gl
value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit")
def execute(filters):
def execute(filters=None):
validate_filters(filters)
data = get_data(filters)
columns = get_columns()
@@ -45,8 +45,8 @@ def validate_filters(filters):
filters.to_date = filters.year_end_date
def get_data(filters):
accounts = frappe.db.sql("""select * from `tabAccount` where company=%s order by lft""",
filters.company, as_dict=True)
accounts = frappe.db.sql("""select name, parent_account, account_name, root_type, report_type, lft, rgt
from `tabAccount` where company=%s order by lft""", filters.company, as_dict=True)
if not accounts:
return None
@@ -56,17 +56,58 @@ def get_data(filters):
min_lft, max_rgt = frappe.db.sql("""select min(lft), max(rgt) from `tabAccount`
where company=%s""", (filters.company,))[0]
gl_entries_by_account = get_gl_entries(filters.company, None, filters.to_date, min_lft, max_rgt,
gl_entries_by_account = get_gl_entries(filters.company, filters.from_date, filters.to_date, min_lft, max_rgt,
ignore_closing_entries=not flt(filters.with_period_closing_entry))
total_row = calculate_values(accounts, gl_entries_by_account, filters)
opening_balances = get_opening_balances(filters)
total_row = calculate_values(accounts, gl_entries_by_account, opening_balances, filters)
accumulate_values_into_parents(accounts, accounts_by_name)
data = prepare_data(accounts, filters, total_row)
return data
def get_opening_balances(filters):
balance_sheet_opening = get_rootwise_opening_balances(filters, "Balance Sheet")
pl_opening = get_rootwise_opening_balances(filters, "Profit and Loss")
balance_sheet_opening.update(pl_opening)
return balance_sheet_opening
def get_rootwise_opening_balances(filters, report_type):
additional_conditions = " and posting_date >= %(year_start_date)s" \
if report_type == "Profit and Loss" else ""
if not flt(filters.with_period_closing_entry):
additional_conditions += " and ifnull(voucher_type, '')!='Period Closing Voucher'"
gle = frappe.db.sql("""
select
account, sum(ifnull(debit, 0)) as opening_debit, sum(ifnull(credit, 0)) as opening_credit
from `tabGL Entry`
where
company=%(company)s
{additional_conditions}
and posting_date < %(from_date)s
and account in (select name from `tabAccount` where report_type=%(report_type)s)
group by account""".format(additional_conditions=additional_conditions),
{
"company": filters.company,
"from_date": filters.from_date,
"report_type": report_type,
"year_start_date": filters.year_start_date
},
as_dict=True)
opening = frappe._dict()
for d in gle:
opening.setdefault(d.account, d)
return opening
def calculate_values(accounts, gl_entries_by_account, filters):
def calculate_values(accounts, gl_entries_by_account, opening_balances, filters):
init = {
"opening_debit": 0.0,
"opening_credit": 0.0,
@@ -88,29 +129,15 @@ def calculate_values(accounts, gl_entries_by_account, filters):
d.update(init.copy())
for entry in gl_entries_by_account.get(d.name, []):
posting_date = getdate(entry.posting_date)
# opening
if posting_date < filters.from_date:
is_valid_opening = (d.root_type in ("Asset", "Liability", "Equity") or
(filters.year_start_date <= posting_date < filters.from_date))
if is_valid_opening:
d["opening_debit"] += flt(entry.debit)
d["opening_credit"] += flt(entry.credit)
elif posting_date <= filters.to_date:
if entry.is_opening == "Yes" and d.root_type in ("Asset", "Liability", "Equity"):
d["opening_debit"] += flt(entry.debit)
d["opening_credit"] += flt(entry.credit)
else:
d["debit"] += flt(entry.debit)
d["credit"] += flt(entry.credit)
d["debit"] += flt(entry.debit)
d["credit"] += flt(entry.credit)
total_row["debit"] += d["debit"]
total_row["credit"] += d["credit"]
# add opening
d["opening_debit"] = opening_balances.get(d.name, {}).get("opening_debit", 0)
d["opening_credit"] = opening_balances.get(d.name, {}).get("opening_credit", 0)
return total_row

View File

@@ -91,7 +91,7 @@ def get_balance_on(account=None, date=None, party_type=None, party=None):
# different filter for group and ledger - improved performance
if acc.is_group:
cond.append("""exists (
select * from `tabAccount` ac where ac.name = gle.account
select name from `tabAccount` ac where ac.name = gle.account
and ac.lft >= %s and ac.rgt <= %s
)""" % (acc.lft, acc.rgt))
else:
@@ -397,7 +397,7 @@ def get_outstanding_invoices(amount_query, account, party_type, party):
for d in outstanding_voucher_list:
payment_amount = frappe.db.sql("""
select ifnull(sum(ifnull({amount_query}, 0)), 0)
select ifnull(sum({amount_query}), 0)
from
`tabGL Entry`
where

View File

@@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd. and Contributors"
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th"
app_color = "#e74c3c"
app_version = "5.0.19"
app_version = "5.0.23"
error_report_email = "support@erpnext.com"

View File

@@ -309,10 +309,9 @@ class ProductionOrder(Document):
self.actual_end_date = None
def validate_delivery_date(self):
if self.docstatus==1:
if self.planned_end_date and self.expected_delivery_date \
and getdate(self.expected_delivery_date) < getdate(self.planned_end_date):
frappe.msgprint(_("Production might not be able to finish by the Expected Delivery Date."))
if self.planned_start_date and self.expected_delivery_date \
and getdate(self.expected_delivery_date) < getdate(self.planned_start_date):
frappe.throw(_("Expected Delivery Date must be greater than Planned Start Date."))
def delete_time_logs(self):
for time_log in frappe.get_all("Time Log", ["name"], {"production_order": self.name}):

View File

@@ -165,4 +165,5 @@ erpnext.patches.v5_0.repost_gle_for_jv_with_multiple_party
erpnext.patches.v5_0.portal_fixes
erpnext.patches.v5_0.reset_values_in_tools
execute:frappe.delete_doc("Page", "users")
erpnext.patches.v5_0.update_material_transferred_for_manufacturing_again
erpnext.patches.v5_0.update_material_transferred_for_manufacturing_again
erpnext.patches.v5_0.index_on_account_and_gl_entry

View File

@@ -0,0 +1,22 @@
from __future__ import unicode_literals
import frappe
def execute():
index_map = {
"Account": ["parent_account", "lft", "rgt"],
"GL Entry": ["posting_date", "account", 'party', "voucher_no"]
}
for dt, indexes in index_map.items():
existing_indexes = [d.Key_name for d in frappe.db.sql("""show index from `tab{0}`
where Column_name != 'name'""".format(dt), as_dict=1)]
for old in existing_indexes:
if old in ("parent", "group_or_ledger", "is_pl_account", "debit_or_credit", "account_name", "company"):
frappe.db.sql("alter table `tab{0}` drop index {1}".format(dt, old))
existing_indexes.remove(old)
for new in indexes:
if new not in existing_indexes:
frappe.db.sql("alter table `tab{0}` add index ({1})".format(dt, new))

View File

@@ -0,0 +1 @@
cur_frm.add_fetch('employee', 'employee_name', 'employee_name');

View File

@@ -2,7 +2,7 @@
"allow_copy": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "Activity Cost - .#",
"autoname": "AC-.#####",
"creation": "2015-03-23 02:00:21.861546",
"custom": 0,
"docstatus": 0,
@@ -31,11 +31,12 @@
},
{
"fieldname": "employee_name",
"fieldtype": "Read Only",
"fieldtype": "Data",
"label": "Employee Name",
"options": "employee.employee_name",
"options": "",
"permlevel": 0,
"precision": ""
"precision": "",
"read_only": 1
},
{
"fieldname": "column_break_2",
@@ -135,7 +136,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-04-14 02:08:33.690406",
"modified": "2015-06-11 06:50:47.999788",
"modified_by": "Administrator",
"module": "Projects",
"name": "Activity Cost",

View File

@@ -15,6 +15,8 @@ class ActivityCost(Document):
self.check_unique()
def set_title(self):
if not self.employee_name:
self.employee_name = frappe.db.get_value("Employee", self.employee, "employee_name")
self.title = _("{0} for {1}").format(self.employee_name, self.activity_type)
def check_unique(self):

View File

@@ -15,16 +15,23 @@ class Project(Document):
def onload(self):
"""Load project tasks for quick view"""
for task in frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc"):
self.append("tasks", {
"title": task.subject,
"status": task.status,
"start_date": task.exp_start_date,
"end_date": task.exp_end_date,
"description": task.description,
"task_id": task.name
})
if not self.get("tasks"):
for task in self.get_tasks():
self.append("tasks", {
"title": task.subject,
"status": task.status,
"start_date": task.exp_start_date,
"end_date": task.exp_end_date,
"description": task.description,
"task_id": task.name
})
def __setup__(self):
self.onload()
def get_tasks(self):
return frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc")
def validate(self):
self.validate_dates()
self.sync_tasks()

View File

@@ -28,7 +28,11 @@ class Task(Document):
def validate(self):
self.validate_dates()
if self.status!=self.get_db_value("status") and self.status == "Closed":
from frappe.desk.form.assign_to import clear
clear(self.doctype, self.name)
def validate_dates(self):
if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'"))
@@ -41,17 +45,17 @@ class Task(Document):
self.reschedule_dependent_tasks()
self.update_percentage()
self.update_project()
def update_percentage(self):
"""update percent complete in project"""
if self.project and not self.flags.from_project:
project = frappe.get_doc("Project", self.project)
project.run_method("update_percent_complete")
def update_total_expense_claim(self):
self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
where project = %s and task = %s and approval_status = "Approved" and docstatus=1""",(self.project, self.name))
def update_time_and_costing(self):
tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date,
sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount,
@@ -64,14 +68,14 @@ class Task(Document):
self.actual_time= tl.time
self.act_start_date= tl.start_date
self.act_end_date= tl.end_date
def update_project(self):
if self.project and frappe.db.exists("Project", self.project):
project = frappe.get_doc("Project", self.project)
project.flags.dont_sync_tasks = True
project.update_costing()
project.save()
def check_recursion(self):
if self.flags.ignore_recursion_check: return
check_list = [['task', 'parent'], ['parent', 'task']]
@@ -88,7 +92,7 @@ class Task(Document):
task_list.append(b[0])
if count == 15:
break
def reschedule_dependent_tasks(self):
end_date = self.exp_end_date or self.act_end_date
if end_date:

View File

@@ -11,19 +11,19 @@ from erpnext.projects.doctype.task.task import CircularReferenceError
class TestTask(unittest.TestCase):
def test_circular_reference(self):
task1 = frappe.new_doc('Task')
task1.update({
"status": "Open",
"status": "Open",
"subject": "_Test Task 1",
"exp_start_date": "2015-1-1",
"exp_end_date": "2015-1-10"
})
task1.save()
task2 = frappe.new_doc('Task')
task2.update({
"status": "Open",
"status": "Open",
"subject": "_Test Task 2",
"exp_start_date": "2015-1-11",
"exp_end_date": "2015-1-15",
@@ -34,10 +34,10 @@ class TestTask(unittest.TestCase):
]
})
task2.save()
task3 = frappe.new_doc('Task')
task3.update({
"status": "Open",
"status": "Open",
"subject": "_Test Task 2",
"exp_start_date": "2015-1-11",
"exp_end_date": "2015-1-15",
@@ -53,13 +53,13 @@ class TestTask(unittest.TestCase):
"task": task3.name
})
self.assertRaises(CircularReferenceError, task1.save)
task1.set("depends_on", [])
task1.save()
task4 = frappe.new_doc('Task')
task4.update({
"status": "Open",
"status": "Open",
"subject": "_Test Task 1",
"exp_start_date": "2015-1-1",
"exp_end_date": "2015-1-15",
@@ -74,20 +74,20 @@ class TestTask(unittest.TestCase):
task3.append("depends_on", {
"task": task4.name
})
def test_reschedule_dependent_task(self):
task1 = frappe.new_doc('Task')
task1.update({
"status": "Open",
"status": "Open",
"subject": "_Test Task 1",
"exp_start_date": "2015-1-1",
"exp_end_date": "2015-1-10"
})
task1.save()
task2 = frappe.new_doc('Task')
task2.update({
"status": "Open",
"status": "Open",
"subject": "_Test Task 2",
"exp_start_date": "2015-1-11",
"exp_end_date": "2015-1-15",
@@ -98,10 +98,10 @@ class TestTask(unittest.TestCase):
]
})
task2.save()
task3 = frappe.new_doc('Task')
task3.update({
"status": "Open",
"status": "Open",
"subject": "_Test Task 3",
"exp_start_date": "2015-1-16",
"exp_end_date": "2015-1-18",
@@ -112,18 +112,18 @@ class TestTask(unittest.TestCase):
]
})
task3.save()
task1.update({
"exp_end_date": "2015-1-20"
})
task1.save()
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
time_log = frappe.new_doc('Time Log')
time_log.update({
"from_time": "2015-1-1",
@@ -131,18 +131,49 @@ class TestTask(unittest.TestCase):
"task": task1.name
})
time_log.submit()
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
time_log.cancel()
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
def test_close_assignment(self):
task = frappe.new_doc("Task")
task.subject = "Test Close Assignment"
task.insert()
def assign():
from frappe.desk.form import assign_to
assign_to.add({
"assign_to": "test@example.com",
"doctype": task.doctype,
"name": task.name,
"description": "Close this task"
})
def get_owner_and_status():
return frappe.db.get_value("ToDo", filters={"reference_type": task.doctype, "reference_name": task.name,
"description": "Close this task"}, fieldname=("owner", "status"), as_dict=True)
assign()
todo = get_owner_and_status()
self.assertEquals(todo.owner, "test@example.com")
self.assertEquals(todo.status, "Open")
# assignment should be
task.load_from_db()
task.status = "Closed"
task.save()
todo = get_owner_and_status()
self.assertEquals(todo.owner, "test@example.com")
self.assertEquals(todo.status, "Closed")

View File

@@ -105,6 +105,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
}
},
barcode: function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if(d.barcode=="" || d.barcode==null) {
// barcode cleared, remove item
d.item_code = "";
}
this.item_code(doc, cdt, cdn);
},
item_code: function(doc, cdt, cdn) {
var me = this;
var item = frappe.get_doc(cdt, cdn);

View File

@@ -81,7 +81,8 @@ erpnext.feature_setup.feature_dict = {
'Item': {'fields': ['barcode']},
'Delivery Note': {'items': ['barcode']},
'Sales Invoice': {'items': ['barcode']},
'Stock Entry': {'items': ['barcode']}
'Stock Entry': {'items': ['barcode']},
'Purchase Receipt': {'items': ['barcode']}
},
'fs_item_group_in_details': {
'Delivery Note': {'items':['item_group']},

View File

@@ -8,6 +8,13 @@ frappe.query_reports["Customers Not Buying Since Long Time"] = {
"label": __("Days Since Last Order"),
"fieldtype": "Int",
"default": 60
},
{
"fieldname":"doctype",
"label": __("Doctype"),
"fieldtype": "Select",
"default": "Sales Order",
"options": "Sales Order\nSales Invoice"
}
]
}

View File

@@ -10,41 +10,51 @@ def execute(filters=None):
if not filters: filters ={}
days_since_last_order = filters.get("days_since_last_order")
doctype = filters.get("doctype")
if cint(days_since_last_order) <= 0:
frappe.throw(_("'Days Since Last Order' must be greater than or equal to zero"))
columns = get_columns()
customers = get_so_details()
customers = get_sales_details(doctype)
data = []
for cust in customers:
if cint(cust[8]) >= cint(days_since_last_order):
cust.insert(7,get_last_so_amt(cust[0]))
cust.insert(7,get_last_sales_amt(cust[0], doctype))
data.append(cust)
return columns, data
def get_so_details():
def get_sales_details(doctype):
cond = """sum(so.base_net_total) as 'total_order_considered',
max(so.posting_date) as 'last_order_date',
DATEDIFF(CURDATE(), max(so.posting_date)) as 'days_since_last_order' """
if doctype == "Sales Order":
cond = """sum(if(so.status = "Stopped",
so.base_net_total * so.per_delivered/100,
so.base_net_total)) as 'total_order_considered',
max(so.transaction_date) as 'last_order_date',
DATEDIFF(CURDATE(), max(so.transaction_date)) as 'days_since_last_order'"""
return frappe.db.sql("""select
cust.name,
cust.customer_name,
cust.territory,
cust.customer_group,
count(distinct(so.name)) as 'num_of_order',
sum(base_net_total) as 'total_order_value',
sum(if(so.status = "Stopped",
so.base_net_total * so.per_delivered/100,
so.base_net_total)) as 'total_order_considered',
max(so.transaction_date) as 'last_sales_order_date',
DATEDIFF(CURDATE(), max(so.transaction_date)) as 'days_since_last_order'
from `tabCustomer` cust, `tabSales Order` so
sum(base_net_total) as 'total_order_value', {0}
from `tabCustomer` cust, `tab{1}` so
where cust.name = so.customer and so.docstatus = 1
group by cust.name
order by 'days_since_last_order' desc """,as_list=1)
order by 'days_since_last_order' desc """.format(cond, doctype), as_list=1)
def get_last_so_amt(customer):
res = frappe.db.sql("""select base_net_total from `tabSales Order`
where customer = %s and docstatus = 1 order by transaction_date desc
limit 1""", customer)
def get_last_sales_amt(customer, doctype):
cond = "posting_date"
if doctype =="Sales Order":
cond = "transaction_date"
res = frappe.db.sql("""select base_net_total from `tab{0}`
where customer = %s and docstatus = 1 order by {1} desc
limit 1""".format(doctype, cond), customer)
return res and res[0][0] or 0
@@ -58,6 +68,6 @@ def get_columns():
_("Total Order Value") + ":Currency:120",
_("Total Order Considered") + ":Currency:160",
_("Last Order Amount") + ":Currency:160",
_("Last Sales Order Date") + ":Date:160",
_("Last Order Date") + ":Date:160",
_("Days Since Last Order") + "::160"
]

View File

@@ -124,15 +124,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
this.apply_pricing_rule();
},
barcode: function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if(d.barcode=="" || d.barcode==null) {
// barcode cleared, remove item
d.item_code = "";
}
this.item_code(doc, cdt, cdn);
},
selling_price_list: function() {
this.apply_price_list();
},

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
import urllib
from frappe.utils.nestedset import NestedSet
from frappe.website.website_generator import WebsiteGenerator
from frappe.website.render import clear_cache
@@ -91,7 +91,7 @@ def get_item_for_list_in_html(context):
# add missing absolute link in files
# user may forget it during upload
if (context.get("website_image") or "").startswith("files/"):
context["website_image"] = "/" + context["website_image"]
context["website_image"] = "/" + urllib.quote(context["website_image"])
return frappe.get_template("templates/includes/product_in_grid.html").render(context)
def get_group_item_count(item_group):

View File

@@ -49,7 +49,7 @@ class NamingSeries(Document):
self.set_series_for(self.select_doc_for_series, series_list)
# create series
map(self.insert_series, [d.split('.')[0] for d in series_list])
map(self.insert_series, [d.split('.')[0] for d in series_list if d.strip()])
msgprint(_("Series Updated"))

View File

@@ -221,7 +221,7 @@
"icon": "icon-ticket",
"idx": 1,
"is_submittable": 1,
"modified": "2015-05-27 15:36:06.818491",
"modified": "2015-06-09 05:47:05.934432",
"modified_by": "Administrator",
"module": "Stock",
"name": "Material Request",

View File

@@ -6,7 +6,13 @@ frappe.listview_settings['Material Request'] = {
} else if(doc.docstatus==1 && flt(doc.per_ordered) < 100) {
return [__("Pending"), "orange", "per_ordered,<,100"];
} else if(doc.docstatus==1 && flt(doc.per_ordered) == 100) {
return [__("Ordered"), "green", "per_ordered,=,100"];
if (doc.material_request_type == "Purchase") {
return [__("Ordered"), "green", "per_ordered,=,100"];
} else if (doc.material_request_type == "Material Transfer") {
return [__("Transfered"), "green", "per_ordered,=,100"];
} else if (doc.material_request_type == "Material Issue") {
return [__("Issued"), "green", "per_ordered,=,100"];
}
}
}
};

View File

@@ -4,6 +4,19 @@
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "barcode",
"fieldtype": "Data",
"label": "Barcode",
"permlevel": 0,
"precision": ""
},
{
"fieldname": "section_break_2",
"fieldtype": "Section Break",
"permlevel": 0,
"precision": ""
},
{
"fieldname": "item_code",
"fieldtype": "Link",
@@ -642,7 +655,7 @@
],
"idx": 1,
"istable": 1,
"modified": "2015-06-02 14:19:13.528248",
"modified": "2015-06-08 08:21:18.024324",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",

View File

@@ -112,7 +112,7 @@ class StockEntry(StockController):
for f in ("uom", "stock_uom", "description", "item_name", "expense_account",
"cost_center", "conversion_factor"):
if f not in ["expense_account", "cost_center"] or not item.get(f):
if f in ["stock_uom", "conversion_factor"] or not item.get(f):
item.set(f, item_details.get(f))
if self.difference_account:
@@ -185,9 +185,6 @@ class StockEntry(StockController):
def validate_production_order(self):
if self.purpose in ("Manufacture", "Material Transfer for Manufacture"):
if not self.bom_no:
frappe.throw(_("BOM No is mandatory"))
# check if production order is entered
if not self.production_order:
frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture"))

View File

@@ -5,12 +5,12 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
"modified": "2015-04-07 08:18:14.440193",
"modified": "2015-06-10 15:52:49.492144",
"modified_by": "Administrator",
"module": "Stock",
"name": "Ordered Items To Be Delivered",
"owner": "Administrator",
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project_name` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.qty as \"Qty:Float:140\",\n `tabSales Order Item`.delivered_qty as \"Delivered Qty:Float:140\",\n (`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0)) as \"Qty to Deliver:Float:140\",\n `tabSales Order Item`.base_rate as \"Rate:Float:140\",\n `tabSales Order Item`.base_amount as \"Amount:Float:140\",\n ((`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0))*`tabSales Order Item`.base_rate) as \"Amount to Deliver:Float:140\",\n `tabBin`.actual_qty as \"Available Qty:Float:120\",\n `tabBin`.projected_qty as \"Projected Qty:Float:120\",\n `tabSales Order`.`delivery_date` as \"Expected Delivery Date:Date:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order Item`.item_group as \"Item Group:Link/Item Group:120\"\nfrom\n `tabSales Order`, `tabSales Order Item`, `tabBin`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Stopped\"\n and ifnull(`tabSales Order Item`.delivered_qty,0) < ifnull(`tabSales Order Item`.qty,0)\n and `tabBin`.item_code = `tabSales Order Item`.item_code\n and `tabBin`.warehouse = `tabSales Order Item`.warehouse\norder by `tabSales Order`.transaction_date asc",
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project_name` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.qty as \"Qty:Float:140\",\n `tabSales Order Item`.delivered_qty as \"Delivered Qty:Float:140\",\n (`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0)) as \"Qty to Deliver:Float:140\",\n `tabSales Order Item`.base_rate as \"Rate:Float:140\",\n `tabSales Order Item`.base_amount as \"Amount:Float:140\",\n ((`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0))*`tabSales Order Item`.base_rate) as \"Amount to Deliver:Float:140\",\n `tabBin`.actual_qty as \"Available Qty:Float:120\",\n `tabBin`.projected_qty as \"Projected Qty:Float:120\",\n `tabSales Order`.`delivery_date` as \"Expected Delivery Date:Date:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order Item`.item_group as \"Item Group:Link/Item Group:120\",\n `tabSales Order Item`.warehouse as \"Warehouse:Link/Warehouse:200\"\nfrom\n `tabSales Order`, `tabSales Order Item`, `tabBin`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Stopped\"\n and ifnull(`tabSales Order Item`.delivered_qty,0) < ifnull(`tabSales Order Item`.qty,0)\n and `tabBin`.item_code = `tabSales Order Item`.item_code\n and `tabBin`.warehouse = `tabSales Order Item`.warehouse\norder by `tabSales Order`.transaction_date asc",
"ref_doctype": "Delivery Note",
"report_name": "Ordered Items To Be Delivered",
"report_type": "Query Report"

View File

@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
version = "5.0.19"
version = "5.0.23"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()