Merge branch 'develop'

This commit is contained in:
Pratik Vyas
2014-12-09 16:40:28 +05:30
22 changed files with 109 additions and 77 deletions

View File

@@ -1 +1 @@
__version__ = '4.12.0' __version__ = '4.13.0'

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.utils import flt, cstr, cint, getdate, add_days, formatdate from frappe.utils import flt, cstr, cint, getdate
from frappe import msgprint, throw, _ from frappe import msgprint, throw, _
from frappe.model.document import Document from frappe.model.document import Document
@@ -176,15 +176,7 @@ class Account(Document):
frappe.throw(_("Due Date cannot be before Posting Date")) frappe.throw(_("Due Date cannot be before Posting Date"))
elif credit_days is not None and diff > credit_days: elif credit_days is not None and diff > credit_days:
is_credit_controller = frappe.db.get_value("Accounts Settings", None, msgprint(_("Note: Due Date exceeds the allowed credit days by {0} day(s)").format(diff - credit_days))
"credit_controller") in frappe.user.get_roles()
if is_credit_controller:
msgprint(_("Note: Due Date exceeds the allowed credit days by {0} day(s)").format(
diff - credit_days))
else:
max_due_date = formatdate(add_days(posting_date, credit_days))
frappe.throw(_("Due Date cannot be after {0}").format(max_due_date))
def validate_trash(self): def validate_trash(self):
"""checks gl entries and if child exists""" """checks gl entries and if child exists"""

View File

@@ -800,7 +800,8 @@
"fieldtype": "Date", "fieldtype": "Date",
"label": "From Date", "label": "From Date",
"no_copy": 1, "no_copy": 1,
"permlevel": 0 "permlevel": 0,
"print_hide": 1
}, },
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
@@ -810,7 +811,8 @@
"fieldtype": "Date", "fieldtype": "Date",
"label": "To Date", "label": "To Date",
"no_copy": 1, "no_copy": 1,
"permlevel": 0 "permlevel": 0,
"print_hide": 1
}, },
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
@@ -878,7 +880,7 @@
"icon": "icon-file-text", "icon": "icon-file-text",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"modified": "2014-10-08 14:23:20.234176", "modified": "2014-11-27 17:28:20.133701",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Purchase Invoice", "name": "Purchase Invoice",

View File

@@ -233,6 +233,11 @@ erpnext.POS = Class.extend({
}, },
make_item_list: function() { make_item_list: function() {
var me = this; var me = this;
if(!this.price_list) {
msgprint(__("Price List not found or disabled"));
return;
}
me.item_timeout = null; me.item_timeout = null;
frappe.call({ frappe.call({
method: 'erpnext.accounts.doctype.sales_invoice.pos.get_items', method: 'erpnext.accounts.doctype.sales_invoice.pos.get_items',

View File

@@ -13,17 +13,17 @@ class AccountsReceivableReport(object):
self.age_as_on = getdate(nowdate()) \ self.age_as_on = getdate(nowdate()) \
if self.filters.report_date > getdate(nowdate()) \ if self.filters.report_date > getdate(nowdate()) \
else self.filters.report_date else self.filters.report_date
def run(self): def run(self):
customer_naming_by = frappe.db.get_value("Selling Settings", None, "cust_master_name") customer_naming_by = frappe.db.get_value("Selling Settings", None, "cust_master_name")
return self.get_columns(customer_naming_by), self.get_data(customer_naming_by) return self.get_columns(customer_naming_by), self.get_data(customer_naming_by)
def get_columns(self, customer_naming_by): def get_columns(self, customer_naming_by):
columns = [ columns = [
_("Posting Date") + ":Date:80", _("Account") + ":Link/Account:150", _("Posting Date") + ":Date:80", _("Account") + ":Link/Account:150",
_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120", _("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120",
_("Due Date") + ":Date:80", _("Due Date") + ":Date:80",
_("Invoiced Amount") + ":Currency:100", _("Payment Received") + ":Currency:100", _("Invoiced Amount") + ":Currency:100", _("Payment Received") + ":Currency:100",
_("Outstanding Amount") + ":Currency:100", _("Age") + ":Int:50", "0-30:Currency:100", _("Outstanding Amount") + ":Currency:100", _("Age") + ":Int:50", "0-30:Currency:100",
"30-60:Currency:100", "60-90:Currency:100", _("90-Above") + ":Currency:100", "30-60:Currency:100", "60-90:Currency:100", _("90-Above") + ":Currency:100",
_("Customer") + ":Link/Customer:200" _("Customer") + ":Link/Customer:200"
@@ -69,27 +69,27 @@ class AccountsReceivableReport(object):
# returns a distinct list # returns a distinct list
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries() return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries()
if getdate(e.posting_date) > report_date])) if getdate(e.posting_date) > report_date]))
def get_entries_till(self, report_date): def get_entries_till(self, report_date):
# returns a generator # returns a generator
return (e for e in self.get_gl_entries() return (e for e in self.get_gl_entries()
if getdate(e.posting_date) <= report_date) if getdate(e.posting_date) <= report_date)
def is_receivable(self, gle, future_vouchers): def is_receivable(self, gle, future_vouchers):
return ( return (
# advance # advance
(not gle.against_voucher) or (not gle.against_voucher) or
# against sales order # against sales order
(gle.against_voucher_type == "Sales Order") or (gle.against_voucher_type == "Sales Order") or
# sales invoice # sales invoice
(gle.against_voucher==gle.voucher_no and gle.debit > 0) or (gle.against_voucher==gle.voucher_no and gle.debit > 0) or
# entries adjusted with future vouchers # entries adjusted with future vouchers
((gle.against_voucher_type, gle.against_voucher) in future_vouchers) ((gle.against_voucher_type, gle.against_voucher) in future_vouchers)
) )
def get_outstanding_amount(self, gle, report_date): def get_outstanding_amount(self, gle, report_date):
payment_received = 0.0 payment_received = 0.0
for e in self.get_gl_entries_for(gle.account, gle.voucher_type, gle.voucher_no): for e in self.get_gl_entries_for(gle.account, gle.voucher_type, gle.voucher_no):
@@ -97,7 +97,7 @@ class AccountsReceivableReport(object):
payment_received += (flt(e.credit) - flt(e.debit)) payment_received += (flt(e.credit) - flt(e.debit))
return flt(gle.debit) - flt(gle.credit) - payment_received return flt(gle.debit) - flt(gle.credit) - payment_received
def get_customer(self, account): def get_customer(self, account):
return self.get_account_map().get(account, {}).get("customer") or "" return self.get_account_map().get(account, {}).get("customer") or ""
@@ -106,25 +106,25 @@ class AccountsReceivableReport(object):
def get_territory(self, account): def get_territory(self, account):
return self.get_account_map().get(account, {}).get("territory") or "" return self.get_account_map().get(account, {}).get("territory") or ""
def get_account_map(self): def get_account_map(self):
if not hasattr(self, "account_map"): if not hasattr(self, "account_map"):
self.account_map = dict(((r.name, r) for r in frappe.db.sql("""select self.account_map = dict(((r.name, r) for r in frappe.db.sql("""select
acc.name, cust.name as customer, cust.customer_name, cust.territory acc.name, cust.name as customer, cust.customer_name, cust.territory
from `tabAccount` acc left join `tabCustomer` cust from `tabAccount` acc left join `tabCustomer` cust
on cust.name=acc.master_name where acc.master_type="Customer" """, as_dict=True))) on cust.name=acc.master_name where acc.master_type="Customer" """, as_dict=True)))
return self.account_map return self.account_map
def get_due_date(self, gle): def get_due_date(self, gle):
if not hasattr(self, "invoice_due_date_map"): if not hasattr(self, "invoice_due_date_map"):
# TODO can be restricted to posting date # TODO can be restricted to posting date
self.invoice_due_date_map = dict(frappe.db.sql("""select name, due_date self.invoice_due_date_map = dict(frappe.db.sql("""select name, due_date
from `tabSales Invoice` where docstatus=1""")) from `tabSales Invoice` where docstatus=1"""))
return gle.voucher_type == "Sales Invoice" \ return gle.voucher_type == "Sales Invoice" \
and self.invoice_due_date_map.get(gle.voucher_no) or "" and self.invoice_due_date_map.get(gle.voucher_no) or ""
def get_gl_entries(self): def get_gl_entries(self):
if not hasattr(self, "gl_entries"): if not hasattr(self, "gl_entries"):
conditions, values = self.prepare_conditions() conditions, values = self.prepare_conditions()
@@ -132,15 +132,15 @@ class AccountsReceivableReport(object):
where docstatus < 2 {0} order by posting_date, account""".format(conditions), where docstatus < 2 {0} order by posting_date, account""".format(conditions),
values, as_dict=True) values, as_dict=True)
return self.gl_entries return self.gl_entries
def prepare_conditions(self): def prepare_conditions(self):
conditions = [""] conditions = [""]
values = {} values = {}
if self.filters.company: if self.filters.company:
conditions.append("company=%(company)s") conditions.append("company=%(company)s")
values["company"] = self.filters.company values["company"] = self.filters.company
if self.filters.account: if self.filters.account:
conditions.append("account=%(account)s") conditions.append("account=%(account)s")
values["account"] = self.filters.account values["account"] = self.filters.account
@@ -149,11 +149,11 @@ class AccountsReceivableReport(object):
if not account_map: if not account_map:
frappe.throw(_("No Customer Accounts found.")) frappe.throw(_("No Customer Accounts found."))
else: else:
accounts_list = ['"{0}"'.format(ac) for ac in account_map] accounts_list = ['"{0}"'.format(ac.replace('"', '\"')) for ac in account_map]
conditions.append("account in ({0})".format(", ".join(accounts_list))) conditions.append("account in ({0})".format(", ".join(accounts_list)))
return " and ".join(conditions), values return " and ".join(conditions), values
def get_gl_entries_for(self, account, against_voucher_type, against_voucher): def get_gl_entries_for(self, account, against_voucher_type, against_voucher):
if not hasattr(self, "gl_entries_map"): if not hasattr(self, "gl_entries_map"):
self.gl_entries_map = {} self.gl_entries_map = {}
@@ -163,7 +163,7 @@ class AccountsReceivableReport(object):
.setdefault(gle.against_voucher_type, {})\ .setdefault(gle.against_voucher_type, {})\
.setdefault(gle.against_voucher, [])\ .setdefault(gle.against_voucher, [])\
.append(gle) .append(gle)
return self.gl_entries_map.get(account, {})\ return self.gl_entries_map.get(account, {})\
.get(against_voucher_type, {})\ .get(against_voucher_type, {})\
.get(against_voucher, []) .get(against_voucher, [])
@@ -176,15 +176,15 @@ def get_ageing_data(age_as_on, entry_date, outstanding_amount):
outstanding_range = [0.0, 0.0, 0.0, 0.0] outstanding_range = [0.0, 0.0, 0.0, 0.0]
if not (age_as_on and entry_date): if not (age_as_on and entry_date):
return [0] + outstanding_range return [0] + outstanding_range
age = (getdate(age_as_on) - getdate(entry_date)).days or 0 age = (getdate(age_as_on) - getdate(entry_date)).days or 0
index = None index = None
for i, days in enumerate([30, 60, 90]): for i, days in enumerate([30, 60, 90]):
if age <= days: if age <= days:
index = i index = i
break break
if index is None: index = 3 if index is None: index = 3
outstanding_range[index] = outstanding_amount outstanding_range[index] = outstanding_amount
return [age] + outstanding_range return [age] + outstanding_range

View File

@@ -685,7 +685,8 @@
"label": "Recurring Type", "label": "Recurring Type",
"no_copy": 1, "no_copy": 1,
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly", "options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
"permlevel": 0 "permlevel": 0,
"print_hide": 1
}, },
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
@@ -695,7 +696,8 @@
"fieldtype": "Date", "fieldtype": "Date",
"label": "From Date", "label": "From Date",
"no_copy": 1, "no_copy": 1,
"permlevel": 0 "permlevel": 0,
"print_hide": 1
}, },
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
@@ -705,7 +707,8 @@
"fieldtype": "Date", "fieldtype": "Date",
"label": "To Date", "label": "To Date",
"no_copy": 1, "no_copy": 1,
"permlevel": 0 "permlevel": 0,
"print_hide": 1
}, },
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
@@ -772,7 +775,7 @@
"icon": "icon-file-text", "icon": "icon-file-text",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"modified": "2014-10-08 14:23:29.718779", "modified": "2014-11-27 17:27:38.839440",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Purchase Order", "name": "Purchase Order",

View File

@@ -437,7 +437,7 @@ class AccountsController(TransactionBase):
for order, jv_list in order_jv_map.items(): for order, jv_list in order_jv_map.items():
for jv in jv_list: for jv in jv_list:
if not advance_jv_against_si or jv not in advance_jv_against_si: if not advance_jv_against_si or jv not in advance_jv_against_si:
frappe.throw(_("Journal Voucher {0} is linked against Order {1}, hence it must be fetched as advance in Invoice as well.") frappe.msgprint(_("Journal Voucher {0} is linked against Order {1}, check if it should be pulled as advance in this invoice.")
.format(jv, order)) .format(jv, order))

View File

@@ -4,7 +4,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors"
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th" app_icon = "icon-th"
app_color = "#e74c3c" app_color = "#e74c3c"
app_version = "4.12.0" app_version = "4.13.0"
error_report_email = "support@erpnext.com" error_report_email = "support@erpnext.com"

View File

@@ -118,3 +118,18 @@ cur_frm.cscript.calculate_total_days = function(doc, dt, dn) {
} }
cur_frm.fields_dict.employee.get_query = erpnext.queries.employee; cur_frm.fields_dict.employee.get_query = erpnext.queries.employee;
frappe.ui.form.on("Leave Application", "leave_approver", function(frm) {
frappe.call({
"method": "frappe.client.get",
args: {
doctype: "User",
name: frm.doc.leave_approver
},
callback: function (data) {
frappe.model.set_value(frm.doctype, frm.docname, "leave_approver_name",
data.message.first_name
+ (data.message.last_name ? (" " + data.message.last_name) : ""))
}
})
})

View File

@@ -24,6 +24,13 @@
"options": "User", "options": "User",
"permlevel": 0 "permlevel": 0
}, },
{
"fieldname": "leave_approver_name",
"fieldtype": "Read Only",
"label": "Leave Approver Name",
"permlevel": 0,
"precision": ""
},
{ {
"fieldname": "leave_type", "fieldname": "leave_type",
"fieldtype": "Link", "fieldtype": "Link",
@@ -184,7 +191,7 @@
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"max_attachments": 3, "max_attachments": 3,
"modified": "2014-09-09 05:35:31.531651", "modified": "2014-12-09 16:33:29.626849",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Leave Application", "name": "Leave Application",

View File

@@ -203,15 +203,15 @@ class LeaveApplication(Document):
def get_holidays(leave_app): def get_holidays(leave_app):
tot_hol = frappe.db.sql("""select count(*) from `tabHoliday` h1, `tabHoliday List` h2, `tabEmployee` e1 tot_hol = frappe.db.sql("""select count(*) from `tabHoliday` h1, `tabHoliday List` h2, `tabEmployee` e1
where e1.name = %s and h1.parent = h2.name and e1.holiday_list = h2.name where e1.name = %s and h1.parent = h2.name and e1.holiday_list = h2.name
and h1.holiday_date between %s and %s""", (leave_app.employee, leave_app.from_date, leave_app.to_date)) and h1.holiday_date between %s and %s""", (leave_app.employee, leave_app.from_date,
leave_app.to_date))
# below line is needed. If an employee hasn't been assigned with any holiday list then above will return 0 rows. # below line is needed. If an employee hasn't been assigned with any holiday list then above will return 0 rows.
tot_hol=tot_hol and flt(tot_hol[0][0]) or 0
if not tot_hol: if not tot_hol:
tot_hol = frappe.db.sql("""select count(*) from `tabHoliday` h1, `tabHoliday List` h2 tot_hol = frappe.db.sql("""select count(*) from `tabHoliday` h1, `tabHoliday List` h2
where h1.parent = h2.name and h1.holiday_date between %s and %s where h1.parent = h2.name and h1.holiday_date between %s and %s
and ifnull(h2.is_default,0) = 1 and h2.fiscal_year = %s""", and ifnull(h2.is_default,0) = 1 and h2.fiscal_year = %s""",
(leave_app.from_date, leave_app.to_date, leave_app.fiscal_year)) (leave_app.from_date, leave_app.to_date, leave_app.fiscal_year))
return tot_hol and flt(tot_hol[0][0]) or 0 return tot_hol and tot_hol[0][0] or 0
@frappe.whitelist() @frappe.whitelist()
def get_total_leave_days(leave_app): def get_total_leave_days(leave_app):

View File

@@ -16,6 +16,15 @@ class TestTimeLog(unittest.TestCase):
self.assertRaises(OverlapError, ts.insert) self.assertRaises(OverlapError, ts.insert)
frappe.db.sql("delete from `tabTime Log`") frappe.db.sql("delete from `tabTime Log`")
def test_negative_hours(self):
frappe.db.sql("delete from `tabTime Log`")
test_time_log = frappe.new_doc("Time Log")
test_time_log.activity_type = "Communication"
test_time_log.from_time = "2013-01-01 11:00:00.000000"
test_time_log.to_time = "2013-01-01 10:00:00.000000"
self.assertRaises(frappe.ValidationError, test_time_log.save)
frappe.db.sql("delete from `tabTime Log`")
test_records = frappe.get_test_records('Time Log') test_records = frappe.get_test_records('Time Log')
test_ignore = ["Time Log Batch", "Sales Invoice"] test_ignore = ["Time Log Batch", "Sales Invoice"]

View File

@@ -19,10 +19,12 @@ class TimeLog(Document):
self.set_status() self.set_status()
self.validate_overlap() self.validate_overlap()
self.calculate_total_hours() self.calculate_total_hours()
def calculate_total_hours(self): def calculate_total_hours(self):
from frappe.utils import time_diff_in_hours from frappe.utils import time_diff_in_hours
self.hours = time_diff_in_hours(self.to_time, self.from_time) self.hours = time_diff_in_hours(self.to_time, self.from_time)
if self.hours < 0:
frappe.throw(_("'From Time' cannot be later than 'To Time'"))
def set_status(self): def set_status(self):
self.status = { self.status = {

View File

@@ -14,8 +14,11 @@
{% if(contact_list[i].phone) { %} {% if(contact_list[i].phone) { %}
{%= __("Phone") %}: {%= contact_list[i].phone %}<br> {%= __("Phone") %}: {%= contact_list[i].phone %}<br>
{% } %} {% } %}
{% if(contact_list[i].mobile_no) { %}
{%= __("Mobile No.") %}: {%= contact_list[i].mobile_no %}<br>
{% } %}
{% if(contact_list[i].email_id) { %} {% if(contact_list[i].email_id) { %}
{%= __("Email Id") %}: {%= contact_list[i].email_id %} {%= __("Email ID") %}: {%= contact_list[i].email_id %}
{% } %} {% } %}
</p> </p>
</div> </div>

View File

@@ -160,7 +160,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"description": "Add to calendar on this date", "description": "Add to calendar on this date",
"fieldname": "contact_date", "fieldname": "contact_date",
"fieldtype": "Date", "fieldtype": "Datetime",
"in_filter": 1, "in_filter": 1,
"label": "Next Contact Date", "label": "Next Contact Date",
"no_copy": 1, "no_copy": 1,
@@ -368,7 +368,7 @@
], ],
"icon": "icon-user", "icon": "icon-user",
"idx": 1, "idx": 1,
"modified": "2014-08-12 05:22:18.801092", "modified": "2014-12-01 08:22:23.286314",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Selling", "module": "Selling",
"name": "Lead", "name": "Lead",

View File

@@ -45,6 +45,7 @@ class Lead(SellingController):
def add_calendar_event(self, opts=None, force=False): def add_calendar_event(self, opts=None, force=False):
super(Lead, self).add_calendar_event({ super(Lead, self).add_calendar_event({
"owner": self.lead_owner, "owner": self.lead_owner,
"starts_on": self.contact_date,
"subject": ('Contact ' + cstr(self.lead_name)), "subject": ('Contact ' + cstr(self.lead_name)),
"description": ('Contact ' + cstr(self.lead_name)) + \ "description": ('Contact ' + cstr(self.lead_name)) + \
(self.contact_by and ('. By : ' + cstr(self.contact_by)) or '') (self.contact_by and ('. By : ' + cstr(self.contact_by)) or '')

View File

@@ -372,7 +372,7 @@
{ {
"description": "Your sales person will get a reminder on this date to contact the customer", "description": "Your sales person will get a reminder on this date to contact the customer",
"fieldname": "contact_date", "fieldname": "contact_date",
"fieldtype": "Date", "fieldtype": "Datetime",
"label": "Next Contact Date", "label": "Next Contact Date",
"oldfieldname": "contact_date", "oldfieldname": "contact_date",
"oldfieldtype": "Date", "oldfieldtype": "Date",
@@ -416,7 +416,7 @@
"icon": "icon-info-sign", "icon": "icon-info-sign",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"modified": "2014-08-12 05:21:51.282397", "modified": "2014-12-01 08:46:35.331148",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Selling", "module": "Selling",
"name": "Opportunity", "name": "Opportunity",

View File

@@ -57,6 +57,7 @@ class Opportunity(TransactionBase):
opts = frappe._dict() opts = frappe._dict()
opts.description = "" opts.description = ""
opts.contact_date = self.contact_date
if self.customer: if self.customer:
if self.contact_person: if self.contact_person:

View File

@@ -157,7 +157,7 @@ class SalesOrder(SellingController):
self.check_credit(self.grand_total) self.check_credit(self.grand_total)
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.grand_total, self) frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.company, self.grand_total, self)
self.update_prevdoc_status('submit') self.update_prevdoc_status('submit')
frappe.db.set(self, 'status', 'Submitted') frappe.db.set(self, 'status', 'Submitted')
@@ -357,17 +357,6 @@ def make_sales_invoice(source_name, target_doc=None):
} }
}, target_doc, postprocess) }, target_doc, postprocess)
def set_advance_vouchers(source, target):
advance_voucher_list = []
advance_voucher = frappe.db.sql("""
select
t1.name as voucher_no, t1.posting_date, t1.remark, t2.account,
t2.name as voucher_detail_no, {amount_query} as payment_amount, t2.is_advance
from
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
""")
return doclist return doclist
@frappe.whitelist() @frappe.whitelist()

View File

@@ -98,9 +98,12 @@ class AuthorizationControl(TransactionBase):
if doc_obj: if doc_obj:
price_list_rate, base_rate = 0, 0 price_list_rate, base_rate = 0, 0
for d in doc_obj.get(doc_obj.fname): for d in doc_obj.get(doc_obj.fname):
if d.base_price_list_rate and d.base_rate: if d.base_rate:
price_list_rate += flt(d.base_price_list_rate) price_list_rate += flt(d.base_price_list_rate) or flt(d.base_rate)
base_rate += flt(d.base_rate) base_rate += flt(d.base_rate)
if doc_obj.get("discount_amount"):
base_rate -= flt(doc_obj.discount_amount)
if price_list_rate: av_dis = 100 - flt(base_rate * 100 / price_list_rate) if price_list_rate: av_dis = 100 - flt(base_rate * 100 / price_list_rate)
final_based_on = ['Grand Total','Average Discount','Customerwise Discount','Itemwise Discount'] final_based_on = ['Grand Total','Average Discount','Customerwise Discount','Itemwise Discount']

View File

@@ -31,7 +31,7 @@
1 Currency = [?] FractionFor e.g. 1 USD = 100 Cent,"1 moneda = [?] Fracción Por ejemplo, 1 USD = 100 Cent" 1 Currency = [?] FractionFor e.g. 1 USD = 100 Cent,"1 moneda = [?] Fracción Por ejemplo, 1 USD = 100 Cent"
1. To maintain the customer wise item code and to make them searchable based on their code use this option,1 . Para mantener el código del artículo sabia cliente y para efectuar búsquedas en ellos en función de su uso de código de esta opción 1. To maintain the customer wise item code and to make them searchable based on their code use this option,1 . Para mantener el código del artículo sabia cliente y para efectuar búsquedas en ellos en función de su uso de código de esta opción
"<a href=""#Sales Browser/Customer Group"">Add / Edit</a>","<a href=""#Sales Browser/Customer grupo""> Añadir / Editar < / a>" "<a href=""#Sales Browser/Customer Group"">Add / Edit</a>","<a href=""#Sales Browser/Customer grupo""> Añadir / Editar < / a>"
"<a href=""#Sales Browser/Item Group"">Add / Edit</a>","<a href=""#Sales Browser/Item grupo""> Añadir / Editar < / a>" "<a href=""#Sales Browser/Item Group"">Add / Edit</a>","<a href=""#Sales Browser/Item Group""> Añadir / Editar < / a>"
"<a href=""#Sales Browser/Territory"">Add / Edit</a>","<a href=""#Sales Browser/Territory""> Añadir / Editar < / a>" "<a href=""#Sales Browser/Territory"">Add / Edit</a>","<a href=""#Sales Browser/Territory""> Añadir / Editar < / a>"
"<h4>Default Template</h4><p>Uses <a href=""http://jinja.pocoo.org/docs/templates/"">Jinja Templating</a> and all the fields of Address (including Custom Fields if any) will be available</p><pre><code>{{ address_line1 }}&lt;br&gt;{% if address_line2 %}{{ address_line2 }}&lt;br&gt;{% endif -%}{{ city }}&lt;br&gt;{% if state %}{{ state }}&lt;br&gt;{% endif -%}{% if pincode %} PIN: {{ pincode }}&lt;br&gt;{% endif -%}{{ country }}&lt;br&gt;{% if phone %}Phone: {{ phone }}&lt;br&gt;{% endif -%}{% if fax %}Fax: {{ fax }}&lt;br&gt;{% endif -%}{% if email_id %}Email: {{ email_id }}&lt;br&gt;{% endif -%}</code></pre>","<h4> defecto plantilla </ h4> <p> Usos <a href=""http://jinja.pocoo.org/docs/templates/""> Jinja plantillas </ a> y todos los campos de la Dirección ( incluyendo campos personalizados en su caso) estará disponible </ p> <pre> <code> {{}} address_line1 <br> {% if address_line2%} {{}} address_line2 <br> { endif% -%} {{city}} <br> {% if estado%} {{Estado}} {% endif <br> -%} {% if%} pincode PIN: {{pincode}} {% endif <br> -%} {{país}} <br> {% if%} de teléfono Teléfono: {{phone}} {<br> endif% -%} {% if%} fax Fax: {{fax}} {% endif <br> -%} {% if%} email_ID Email: {{}} email_ID <br> ; {% endif -%} </ code> </ pre>" "<h4>Default Template</h4><p>Uses <a href=""http://jinja.pocoo.org/docs/templates/"">Jinja Templating</a> and all the fields of Address (including Custom Fields if any) will be available</p><pre><code>{{ address_line1 }}&lt;br&gt;{% if address_line2 %}{{ address_line2 }}&lt;br&gt;{% endif -%}{{ city }}&lt;br&gt;{% if state %}{{ state }}&lt;br&gt;{% endif -%}{% if pincode %} PIN: {{ pincode }}&lt;br&gt;{% endif -%}{{ country }}&lt;br&gt;{% if phone %}Phone: {{ phone }}&lt;br&gt;{% endif -%}{% if fax %}Fax: {{ fax }}&lt;br&gt;{% endif -%}{% if email_id %}Email: {{ email_id }}&lt;br&gt;{% endif -%}</code></pre>","<h4> defecto plantilla </ h4> <p> Usos <a href=""http://jinja.pocoo.org/docs/templates/""> Jinja plantillas </ a> y todos los campos de la Dirección ( incluyendo campos personalizados en su caso) estará disponible </ p> <pre> <code> {{}} address_line1 <br> {% if address_line2%} {{}} address_line2 <br> { endif% -%} {{city}} <br> {% if estado%} {{Estado}} {% endif <br> -%} {% if%} pincode PIN: {{pincode}} {% endif <br> -%} {{país}} <br> {% if%} de teléfono Teléfono: {{phone}} {<br> endif% -%} {% if%} fax Fax: {{fax}} {% endif <br> -%} {% if%} email_ID Email: {{}} email_ID <br> ; {% endif -%} </ code> </ pre>"
A Customer Group exists with same name please change the Customer name or rename the Customer Group,"Existe un Grupo de Clientes con el mismo nombre, por favor cambie el nombre del Cliente o cambie el nombre del Grupo de Clientes" A Customer Group exists with same name please change the Customer name or rename the Customer Group,"Existe un Grupo de Clientes con el mismo nombre, por favor cambie el nombre del Cliente o cambie el nombre del Grupo de Clientes"
@@ -2745,7 +2745,7 @@ Statement of Account,Estado de cuenta
Static Parameters,Parámetros estáticos Static Parameters,Parámetros estáticos
Status,estado Status,estado
Status must be one of {0},Estado debe ser uno de {0} Status must be one of {0},Estado debe ser uno de {0}
Status of {0} {1} is now {2},Situación de {0} {1} { 2 es ahora } Status of {0} {1} is now {2},Situación de {0} {1} {2} es ahora
Status updated to {0},Estado actualizado a {0} Status updated to {0},Estado actualizado a {0}
Statutory info and other general information about your Supplier,Información legal y otra información general acerca de su proveedor Statutory info and other general information about your Supplier,Información legal y otra información general acerca de su proveedor
Stay Updated,Manténgase actualizado Stay Updated,Manténgase actualizado
1 (Half Day) (Medio día)
31 1 Currency = [?] FractionFor e.g. 1 USD = 100 Cent 1 moneda = [?] Fracción Por ejemplo, 1 USD = 100 Cent
32 1. To maintain the customer wise item code and to make them searchable based on their code use this option 1 . Para mantener el código del artículo sabia cliente y para efectuar búsquedas en ellos en función de su uso de código de esta opción
33 <a href="#Sales Browser/Customer Group">Add / Edit</a> <a href="#Sales Browser/Customer grupo"> Añadir / Editar < / a>
34 <a href="#Sales Browser/Item Group">Add / Edit</a> <a href="#Sales Browser/Item grupo"> Añadir / Editar < / a> <a href="#Sales Browser/Item Group"> Añadir / Editar < / a>
35 <a href="#Sales Browser/Territory">Add / Edit</a> <a href="#Sales Browser/Territory"> Añadir / Editar < / a>
36 <h4>Default Template</h4><p>Uses <a href="http://jinja.pocoo.org/docs/templates/">Jinja Templating</a> and all the fields of Address (including Custom Fields if any) will be available</p><pre><code>{{ address_line1 }}&lt;br&gt;{% if address_line2 %}{{ address_line2 }}&lt;br&gt;{% endif -%}{{ city }}&lt;br&gt;{% if state %}{{ state }}&lt;br&gt;{% endif -%}{% if pincode %} PIN: {{ pincode }}&lt;br&gt;{% endif -%}{{ country }}&lt;br&gt;{% if phone %}Phone: {{ phone }}&lt;br&gt;{% endif -%}{% if fax %}Fax: {{ fax }}&lt;br&gt;{% endif -%}{% if email_id %}Email: {{ email_id }}&lt;br&gt;{% endif -%}</code></pre> <h4> defecto plantilla </ h4> <p> Usos <a href="http://jinja.pocoo.org/docs/templates/"> Jinja plantillas </ a> y todos los campos de la Dirección ( incluyendo campos personalizados en su caso) estará disponible </ p> <pre> <code> {{}} address_line1 <br> {% if address_line2%} {{}} address_line2 <br> { endif% -%} {{city}} <br> {% if estado%} {{Estado}} {% endif <br> -%} {% if%} pincode PIN: {{pincode}} {% endif <br> -%} {{país}} <br> {% if%} de teléfono Teléfono: {{phone}} {<br> endif% -%} {% if%} fax Fax: {{fax}} {% endif <br> -%} {% if%} email_ID Email: {{}} email_ID <br> ; {% endif -%} </ code> </ pre>
37 A Customer Group exists with same name please change the Customer name or rename the Customer Group Existe un Grupo de Clientes con el mismo nombre, por favor cambie el nombre del Cliente o cambie el nombre del Grupo de Clientes
2745 Statutory info and other general information about your Supplier Información legal y otra información general acerca de su proveedor
2746 Stay Updated Manténgase actualizado
2747 Stock valores
2748 Stock Adjustment Stock de Ajuste
2749 Stock Adjustment Account Cuenta de Ajuste
2750 Stock Ageing Stock Envejecimiento
2751 Stock Analytics Analytics archivo

View File

@@ -1,7 +1,7 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
import os import os
version = "4.12.0" version = "4.13.0"
with open("requirements.txt", "r") as f: with open("requirements.txt", "r") as f:
install_requires = f.readlines() install_requires = f.readlines()