Merge branch 'edge' of github.com:webnotes/erpnext into edge
diff --git a/accounts/Print Format/SalesInvoice/SalesInvoice.html b/accounts/Print Format/SalesInvoice/SalesInvoice.html
new file mode 100644
index 0000000..6acdc52
--- /dev/null
+++ b/accounts/Print Format/SalesInvoice/SalesInvoice.html
@@ -0,0 +1,133 @@
+{%- if doc.letter_head -%}
+ {{ webnotes.conn.get_value("Letter Head", doc.letter_head, "content") }}
+{%- endif -%}
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan="2"><h1>{{ doc.select_print_heading or 'Invoice' }}</h1></td></tr>
+ <tr><td colspan="2"><h3>{{ doc.name }}</h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td>{{ doc.customer_name }}</td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td>{{ doc.address_display.replace("\n", "<br>") }}</td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td>{{ doc.contact_display }}</td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=40%><b>Invoice Date</b></td>
+ <td>{{ utils.formatdate(doc.posting_date) }}</td>
+ <tr>
+ {%- if doc.convert_into_recurring_invoice and doc.recurring_id -%}
+ <tr>
+ <td width=40%><b>Invoice Period</b></td>
+ <td>{{ (utils.formatdate(doc.invoice_period_from_date)) +
+ ' to ' + utils.formatdate(doc.invoice_period_to_date) }}</td>
+ <tr>
+ {%- endif -%}
+ <tr>
+ <td><b>Due Date</b></td>
+ <td>{{ utils.formatdate(doc.due_date) }}</td>
+ <tr>
+ </tbody></table></td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
+<div class='common page-body'>
+ <!--
+ Page Body will contain
+ + table 2
+ - Sales Invoice Data
+ -->
+ <table class="table table-bordered">
+ <tbody>
+ <tr>
+ <th>Sr</th>
+ <th>Item Name</th>
+ <th>Description</th>
+ <th>Qty</th>
+ <th>UoM</th>
+ <th>Basic Rate</th>
+ <th>Amount</th>
+ </tr>
+ {%- for row in doclist.get({"doctype":"Sales Invoice Item"}) %}
+ <tr>
+ <td style="width: 3%;">{{ row.idx }}</td>
+ <td style="width: 20%;">{{ row.item_name }}</td>
+ <td style="width: 37%;">{{ row.description }}</td>
+ <td style="width: 5%; text-align: right;">{{ row.qty }}</td>
+ <td style="width: 5%;">{{ row.stock_uom }}</td>
+ <td style="width: 15%; text-align: right;">{{ utils.fmt_money(row.export_rate, currency=doc.currency) }}</td>
+ <td style="width: 15%; text-align: right;">{{ utils.fmt_money(row.export_amount, currency=doc.currency) }}</td>
+ </tr>
+ {% endfor -%}
+ </tbody>
+ </table>
+</div>
+<div class='common page-footer'>
+ <!--
+ Page Footer will contain
+ + table 3
+ - Terms and Conditions
+ - Total Rounded Amount Calculation
+ - Total Rounded Amount in Words
+ -->
+ <table class='footer-table' width=100% cellspacing=0>
+ <thead>
+
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60% style='padding-right: 10px;'>
+ <b>Terms, Conditions & Other Information:</b><br />
+ {{ doc.terms }}
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td width=40% style="text-align: right;">{{
+ utils.fmt_money(doc.net_total/doc.conversion_rate, currency=doc.currency)
+ }}</td>
+ </tr>
+ {%- for charge in doclist.get({"doctype":"Sales Taxes and Charges"}) -%}
+ {%- if not charge.included_in_print_rate -%}
+ <tr>
+ <td>{{ charge.description }}</td>
+ <td style="text-align: right;">{{ utils.fmt_money(charge.tax_amount / doc.conversion_rate, currency=doc.currency) }}</td>
+ </tr>
+ {%- endif -%}
+ {%- endfor -%}
+ <tr>
+ <td>Grand Total</td>
+ <td style="text-align: right;">{{ utils.fmt_money(doc.grand_total_export, currency=doc.currency) }}</td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td style="text-align: right;">{{ utils.fmt_money(doc.rounded_total_export, currency=doc.currency) }}</td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i>{{ doc.in_words_export }}</i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+ </tfoot>
+ </table>
+</div>
diff --git a/accounts/Print Format/SalesInvoice/SalesInvoice.txt b/accounts/Print Format/SalesInvoice/SalesInvoice.txt
new file mode 100644
index 0000000..d2b1cdb
--- /dev/null
+++ b/accounts/Print Format/SalesInvoice/SalesInvoice.txt
@@ -0,0 +1,20 @@
+[
+ {
+ "creation": "2013-03-21 15:24:28",
+ "docstatus": 0,
+ "modified": "2013-03-21 15:26:21",
+ "modified_by": "Administrator",
+ "owner": "Administrator"
+ },
+ {
+ "doc_type": "Sales Invoice",
+ "doctype": "Print Format",
+ "module": "Accounts",
+ "name": "__common__",
+ "standard": "Yes"
+ },
+ {
+ "doctype": "Print Format",
+ "name": "SalesInvoice"
+ }
+]
\ No newline at end of file
diff --git a/accounts/doctype/fiscal_year/test_fiscal_year.py b/accounts/doctype/fiscal_year/test_fiscal_year.py
index e031a19..b209b39 100644
--- a/accounts/doctype/fiscal_year/test_fiscal_year.py
+++ b/accounts/doctype/fiscal_year/test_fiscal_year.py
@@ -10,5 +10,15 @@
"doctype": "Fiscal Year",
"year": "_Test Fiscal Year 2014",
"year_start_date": "2014-01-01"
- }]
+ }],
+ [{
+ "doctype": "Fiscal Year",
+ "year": "_Test Fiscal Year 2015",
+ "year_start_date": "2015-01-01"
+ }],
+ [{
+ "doctype": "Fiscal Year",
+ "year": "_Test Fiscal Year 2016",
+ "year_start_date": "2016-01-01"
+ }],
]
\ No newline at end of file
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index f29c2e9..22ac845 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -17,7 +17,9 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import add_days, cint, cstr, date_diff, flt, getdate, nowdate
+from webnotes.utils import add_days, cint, cstr, date_diff, flt, getdate, nowdate, \
+ get_first_day, get_last_day
+
from webnotes.utils.email_lib import sendmail
from webnotes.utils import comma_and
from webnotes.model.doc import make_autoname
@@ -891,25 +893,18 @@
next_date = get_next_date(self.doc.posting_date,
month_map[self.doc.recurring_type], cint(self.doc.repeat_on_day_of_month))
+
webnotes.conn.set(self.doc, 'next_date', next_date)
def get_next_date(dt, mcount, day=None):
- import datetime
- month = getdate(dt).month + mcount
- year = getdate(dt).year
- if not day:
- day = getdate(dt).day
- if month > 12:
- month, year = month-12, year+1
- try:
- next_month_date = datetime.date(year, month, day)
- except:
- import calendar
- last_day = calendar.monthrange(year, month)[1]
- next_month_date = datetime.date(year, month, last_day)
- return next_month_date.strftime("%Y-%m-%d")
-
-def manage_recurring_invoices(next_date=None):
+ dt = getdate(dt)
+
+ from dateutil.relativedelta import relativedelta
+ dt += relativedelta(months=mcount, day=day)
+
+ return dt
+
+def manage_recurring_invoices(next_date=None, commit=True):
"""
Create recurring invoices on specific date by copying the original one
and notify the concerned people
@@ -929,19 +924,22 @@
ref_wrapper = webnotes.bean('Sales Invoice', ref_invoice)
new_invoice_wrapper = make_new_invoice(ref_wrapper, next_date)
send_notification(new_invoice_wrapper)
- webnotes.conn.commit()
+ if commit:
+ webnotes.conn.commit()
except:
- webnotes.conn.rollback()
+ if commit:
+ webnotes.conn.rollback()
- webnotes.conn.begin()
- webnotes.conn.sql("update `tabSales Invoice` set \
- convert_into_recurring_invoice = 0 where name = %s", ref_invoice)
- notify_errors(ref_invoice, ref_wrapper.doc.owner)
- webnotes.conn.commit()
+ webnotes.conn.begin()
+ webnotes.conn.sql("update `tabSales Invoice` set \
+ convert_into_recurring_invoice = 0 where name = %s", ref_invoice)
+ notify_errors(ref_invoice, ref_wrapper.doc.owner)
+ webnotes.conn.commit()
exception_list.append(webnotes.getTraceback())
finally:
- webnotes.conn.begin()
+ if commit:
+ webnotes.conn.begin()
if exception_list:
exception_message = "\n\n".join([cstr(d) for d in exception_list])
@@ -953,19 +951,27 @@
new_invoice = clone(ref_wrapper)
mcount = month_map[ref_wrapper.doc.recurring_type]
-
+
+ invoice_period_from_date = get_next_date(ref_wrapper.doc.invoice_period_from_date, mcount)
+
+ # get last day of the month to maintain period if the from date is first day of its own month
+ # and to date is the last day of its own month
+ if (cstr(get_first_day(ref_wrapper.doc.invoice_period_from_date)) == \
+ cstr(ref_wrapper.doc.invoice_period_from_date)) and \
+ (cstr(get_last_day(ref_wrapper.doc.invoice_period_to_date)) == \
+ cstr(ref_wrapper.doc.invoice_period_to_date)):
+ invoice_period_to_date = get_last_day(get_next_date(ref_wrapper.doc.invoice_period_to_date,
+ mcount))
+ else:
+ invoice_period_to_date = get_next_date(ref_wrapper.doc.invoice_period_to_date, mcount)
+
new_invoice.doc.fields.update({
"posting_date": posting_date,
"aging_date": posting_date,
-
"due_date": add_days(posting_date, cint(date_diff(ref_wrapper.doc.due_date,
ref_wrapper.doc.posting_date))),
-
- "invoice_period_from_date": \
- get_next_date(ref_wrapper.doc.invoice_period_from_date, mcount),
-
- "invoice_period_to_date": \
- get_next_date(ref_wrapper.doc.invoice_period_to_date, mcount),
+ "invoice_period_from_date": invoice_period_from_date,
+ "invoice_period_to_date": invoice_period_to_date,
"fiscal_year": get_fiscal_year(posting_date)[0],
"owner": ref_wrapper.doc.owner,
})
diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt
index 35710b4..462565c 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-03-12 11:56:25",
+ "creation": "2013-03-20 17:01:58",
"docstatus": 0,
- "modified": "2013-03-12 14:31:24",
+ "modified": "2013-03-20 19:17:38",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -1093,7 +1093,7 @@
"description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc ",
"doctype": "DocField",
"fieldname": "repeat_on_day_of_month",
- "fieldtype": "Data",
+ "fieldtype": "Int",
"label": "Repeat on Day of Month",
"no_copy": 1,
"print_hide": 1
diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py
index b63642c..92feae8 100644
--- a/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -332,7 +332,142 @@
self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
where against_invoice=%s""", si.doc.name))
+
+ def test_recurring_invoice(self):
+ from webnotes.utils import now_datetime, get_first_day, get_last_day, add_to_date
+ today = now_datetime().date()
+ base_si = webnotes.bean(copy=test_records[0])
+ base_si.doc.fields.update({
+ "convert_into_recurring_invoice": 1,
+ "recurring_type": "Monthly",
+ "notification_email_address": "test@example.com, test1@example.com, test2@example.com",
+ "repeat_on_day_of_month": today.day,
+ "posting_date": today,
+ "invoice_period_from_date": get_first_day(today),
+ "invoice_period_to_date": get_last_day(today)
+ })
+
+ # monthly
+ si1 = webnotes.bean(copy=base_si.doclist)
+ si1.insert()
+ si1.submit()
+ self._test_recurring_invoice(si1, True)
+
+ # monthly without a first and last day period
+ si2 = webnotes.bean(copy=base_si.doclist)
+ si2.doc.fields.update({
+ "invoice_period_from_date": today,
+ "invoice_period_to_date": add_to_date(today, days=30)
+ })
+ si2.insert()
+ si2.submit()
+ self._test_recurring_invoice(si2, False)
+
+ # quarterly
+ si3 = webnotes.bean(copy=base_si.doclist)
+ si3.doc.fields.update({
+ "recurring_type": "Quarterly",
+ "invoice_period_from_date": get_first_day(today),
+ "invoice_period_to_date": get_last_day(add_to_date(today, months=3))
+ })
+ si3.insert()
+ si3.submit()
+ self._test_recurring_invoice(si3, True)
+
+ # quarterly without a first and last day period
+ si4 = webnotes.bean(copy=base_si.doclist)
+ si4.doc.fields.update({
+ "recurring_type": "Quarterly",
+ "invoice_period_from_date": today,
+ "invoice_period_to_date": add_to_date(today, months=3)
+ })
+ si4.insert()
+ si4.submit()
+ self._test_recurring_invoice(si4, False)
+
+ # yearly
+ si5 = webnotes.bean(copy=base_si.doclist)
+ si5.doc.fields.update({
+ "recurring_type": "Yearly",
+ "invoice_period_from_date": get_first_day(today),
+ "invoice_period_to_date": get_last_day(add_to_date(today, years=1))
+ })
+ si5.insert()
+ si5.submit()
+ self._test_recurring_invoice(si5, True)
+
+ # yearly without a first and last day period
+ si6 = webnotes.bean(copy=base_si.doclist)
+ si6.doc.fields.update({
+ "recurring_type": "Yearly",
+ "invoice_period_from_date": today,
+ "invoice_period_to_date": add_to_date(today, years=1)
+ })
+ si6.insert()
+ si6.submit()
+ self._test_recurring_invoice(si6, False)
+
+ # change posting date but keep recuring day to be today
+ si7 = webnotes.bean(copy=base_si.doclist)
+ si7.doc.fields.update({
+ "posting_date": add_to_date(today, days=-3)
+ })
+ si7.insert()
+ si7.submit()
+
+ # setting so that _test function works
+ si7.doc.posting_date = today
+ self._test_recurring_invoice(si7, True)
+
+ def _test_recurring_invoice(self, base_si, first_and_last_day):
+ from webnotes.utils import add_months, get_last_day, getdate
+ from accounts.doctype.sales_invoice.sales_invoice import manage_recurring_invoices
+
+ no_of_months = ({"Monthly": 1, "Quarterly": 3, "Yearly": 12})[base_si.doc.recurring_type]
+
+ def _test(i):
+ self.assertEquals(i+1, webnotes.conn.sql("""select count(*) from `tabSales Invoice`
+ where recurring_id=%s and docstatus=1""", base_si.doc.recurring_id)[0][0])
+
+ next_date = add_months(base_si.doc.posting_date, no_of_months)
+
+ manage_recurring_invoices(next_date=next_date, commit=False)
+
+ recurred_invoices = webnotes.conn.sql("""select name from `tabSales Invoice`
+ where recurring_id=%s and docstatus=1 order by name desc""", base_si.doc.recurring_id)
+
+ self.assertEquals(i+2, len(recurred_invoices))
+
+ new_si = webnotes.bean("Sales Invoice", recurred_invoices[0][0])
+
+ for fieldname in ["convert_into_recurring_invoice", "recurring_type",
+ "repeat_on_day_of_month", "notification_email_address"]:
+ self.assertEquals(base_si.doc.fields.get(fieldname),
+ new_si.doc.fields.get(fieldname))
+
+ self.assertEquals(new_si.doc.posting_date, unicode(next_date))
+
+ self.assertEquals(new_si.doc.invoice_period_from_date,
+ unicode(add_months(base_si.doc.invoice_period_from_date, no_of_months)))
+
+ if first_and_last_day:
+ self.assertEquals(new_si.doc.invoice_period_to_date,
+ unicode(get_last_day(add_months(base_si.doc.invoice_period_to_date,
+ no_of_months))))
+ else:
+ self.assertEquals(new_si.doc.invoice_period_to_date,
+ unicode(add_months(base_si.doc.invoice_period_to_date, no_of_months)))
+
+ self.assertEquals(getdate(new_si.doc.posting_date).day,
+ base_si.doc.repeat_on_day_of_month)
+
+ return new_si
+
+ # if yearly, test 3 repetitions, else test 13 repetitions
+ count = no_of_months == 12 and 3 or 13
+ for i in xrange(count):
+ base_si = _test(i)
test_dependencies = ["Journal Voucher", "POS Setting"]
diff --git a/public/js/website_utils.js b/public/js/website_utils.js
index 65f7a69..8462c3d 100644
--- a/public/js/website_utils.js
+++ b/public/js/website_utils.js
@@ -70,7 +70,8 @@
// update login
var full_name = getCookie("full_name");
if(full_name) {
- $("#user-tools").html(repl('<a href="account" title="My Account" id="user-full-name">%(full_name)s</a> | \
+ $("#user-tools").html(repl('<a href="profile" title="My Profile" id="user-full-name">%(full_name)s</a> | \
+ <a href="account" title="My Account">My Account</a> | \
<a href="cart" title="Shopping Cart"><i class="icon-shopping-cart"></i> (%(count)s)</a> | \
<a href="server.py?cmd=web_logout" title="Sign Out"><i class="icon-signout"></i></a>', {
full_name: full_name,
diff --git a/selling/doctype/sales_common/sales_common.js b/selling/doctype/sales_common/sales_common.js
index 867a711..d34261d 100644
--- a/selling/doctype/sales_common/sales_common.js
+++ b/selling/doctype/sales_common/sales_common.js
@@ -310,7 +310,8 @@
var callback = function(r, rt) {
cur_frm.cscript.item_code(doc, cdt, cdn);
}
- get_server_fields('get_barcode_details', d.barcode, cur_frm.cscript.fname, doc, cdt, cdn, 1, callback);
+ get_server_fields('get_barcode_details', d.barcode, cur_frm.cscript.fname,
+ doc, cdt, cdn, 1, callback);
}
cur_frm.fields_dict[cur_frm.cscript.fname].grid.get_field('batch_no').get_query =
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index 5009c4e..91b88a4 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -352,4 +352,20 @@
return get_obj('Sales Common').get_item_list( self, is_stopped)
def on_update(self):
- pass
\ No newline at end of file
+ pass
+
+@webnotes.whitelist()
+def get_orders():
+ # find customer id
+ customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user},
+ "customer")
+
+ if customer:
+ orders = webnotes.conn.sql("""select name, creation, currency from `tabSales Order`
+ where customer=%s""", customer, as_dict=1)
+ for order in orders:
+ order.items = webnotes.conn.sql("""select item_name, qty, export_rate, delivered_qty
+ from `tabSales Order Item` where parent=%s order by idx""", order.name, as_dict=1)
+ return orders
+ else:
+ return []
\ No newline at end of file
diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py
index 3cc565e..ebadeab 100644
--- a/setup/doctype/backup_manager/backup_dropbox.py
+++ b/setup/doctype/backup_manager/backup_dropbox.py
@@ -113,7 +113,7 @@
while uploader.offset < size:
try:
uploader.upload_chunked()
- finish(folder + '/' + os.path.basename(filename), overwrite='True')
+ uploader.finish(folder + '/' + os.path.basename(filename), overwrite='True')
except rest.ErrorResponse, e:
pass
else:
diff --git a/setup/doctype/global_defaults/global_defaults.py b/setup/doctype/global_defaults/global_defaults.py
index 8d94a03..f68a6d1 100644
--- a/setup/doctype/global_defaults/global_defaults.py
+++ b/setup/doctype/global_defaults/global_defaults.py
@@ -21,6 +21,7 @@
from webnotes.utils import cint
keydict = {
+ "print_style": "print_style",
"fiscal_year": "current_fiscal_year",
'company': 'default_company',
'currency': 'default_currency',
diff --git a/setup/doctype/global_defaults/global_defaults.txt b/setup/doctype/global_defaults/global_defaults.txt
index 6317439..ac1671e 100644
--- a/setup/doctype/global_defaults/global_defaults.txt
+++ b/setup/doctype/global_defaults/global_defaults.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-21 14:54:43",
+ "creation": "2013-02-21 12:28:24",
"docstatus": 0,
- "modified": "2013-03-19 14:46:49",
+ "modified": "2013-03-21 15:42:59",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -27,8 +27,6 @@
"permlevel": 0
},
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"doctype": "DocPerm",
"name": "__common__",
@@ -61,6 +59,19 @@
},
{
"doctype": "DocField",
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break"
+ },
+ {
+ "description": "For Server Side Print Formats",
+ "doctype": "DocField",
+ "fieldname": "print_style",
+ "fieldtype": "Select",
+ "label": "Print Format Style",
+ "options": "Standard\nClassic\nModern\nSpartan"
+ },
+ {
+ "doctype": "DocField",
"fieldname": "company",
"fieldtype": "Section Break",
"label": "Company"
@@ -425,6 +436,11 @@
"label": "SMS Sender Name"
},
{
+ "amend": 0,
+ "cancel": 0,
+ "doctype": "DocPerm"
+ },
+ {
"doctype": "DocPerm"
}
]
\ No newline at end of file
diff --git a/setup/doctype/item_group/item_group.txt b/setup/doctype/item_group/item_group.txt
index 5976be6..d9c6ffe 100644
--- a/setup/doctype/item_group/item_group.txt
+++ b/setup/doctype/item_group/item_group.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:23",
+ "creation": "2013-01-23 20:00:16",
"docstatus": 0,
- "modified": "2013-01-22 14:56:03",
+ "modified": "2013-03-20 15:09:28",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -125,6 +125,13 @@
},
{
"doctype": "DocField",
+ "fieldname": "item_website_specifications",
+ "fieldtype": "Table",
+ "label": "Item Website Specifications",
+ "options": "Item Website Specification"
+ },
+ {
+ "doctype": "DocField",
"fieldname": "lft",
"fieldtype": "Int",
"hidden": 1,
@@ -175,6 +182,20 @@
"print_hide": 1
},
{
+ "cancel": 1,
+ "create": 1,
+ "doctype": "DocPerm",
+ "role": "System Manager",
+ "write": 1
+ },
+ {
+ "cancel": 1,
+ "create": 1,
+ "doctype": "DocPerm",
+ "role": "Material Master Manager",
+ "write": 1
+ },
+ {
"amend": 0,
"cancel": 0,
"create": 0,
@@ -189,19 +210,5 @@
"doctype": "DocPerm",
"role": "Material User",
"write": 0
- },
- {
- "cancel": 1,
- "create": 1,
- "doctype": "DocPerm",
- "role": "System Manager",
- "write": 1
- },
- {
- "cancel": 1,
- "create": 1,
- "doctype": "DocPerm",
- "role": "Material Master Manager",
- "write": 1
}
]
\ No newline at end of file
diff --git a/stock/doctype/item/item.js b/stock/doctype/item/item.js
index 5b32a34..8b3e044 100644
--- a/stock/doctype/item/item.js
+++ b/stock/doctype/item/item.js
@@ -137,3 +137,17 @@
+ wn.meta.get_docfield(doc.doctype, "description_html").label);
}
};
+
+cur_frm.cscript.copy_from_item_group = function(doc) {
+ wn.model.with_doc("Item Group", doc.item_group, function() {
+ $.each(wn.model.get("Item Website Specification", {parent:doc.item_group}),
+ function(i, d) {
+ var n = wn.model.add_child(doc, "Item Website Specification",
+ "item_website_specifications");
+ n.label = d.label;
+ n.description = d.description;
+ }
+ );
+ cur_frm.refresh();
+ });
+}
diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt
index 036b9d5..b7f7be4 100644
--- a/stock/doctype/item/item.txt
+++ b/stock/doctype/item/item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-21 14:54:43",
+ "creation": "2013-03-07 15:53:11",
"docstatus": 0,
- "modified": "2013-03-06 16:02:47",
+ "modified": "2013-03-20 15:10:12",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -33,7 +33,6 @@
"parent": "Item",
"parentfield": "permissions",
"parenttype": "DocType",
- "permlevel": 0,
"read": 1,
"report": 1,
"submit": 0
@@ -786,6 +785,12 @@
"fieldtype": "Section Break"
},
{
+ "doctype": "DocField",
+ "fieldname": "copy_from_item_group",
+ "fieldtype": "Button",
+ "label": "Copy From Item Group"
+ },
+ {
"depends_on": "show_in_website",
"doctype": "DocField",
"fieldname": "item_website_specifications",
@@ -804,6 +809,24 @@
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
+ "permlevel": 0,
+ "role": "System Manager",
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 1,
+ "role": "Material Master Manager",
+ "write": 0
+ },
+ {
+ "cancel": 1,
+ "create": 1,
+ "doctype": "DocPerm",
+ "permlevel": 0,
"role": "Material Master Manager",
"write": 1
},
@@ -812,6 +835,15 @@
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
+ "permlevel": 1,
+ "role": "System Manager"
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 1,
"role": "Material Manager",
"write": 0
},
@@ -820,6 +852,25 @@
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
+ "permlevel": 0,
+ "role": "Material Manager",
+ "write": 0
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 1,
+ "role": "Material User",
+ "write": 0
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 0,
"role": "Material User",
"write": 0
}
diff --git a/support/doctype/support_ticket/support_ticket.py b/support/doctype/support_ticket/support_ticket.py
index 170497d..1fe2c2d 100644
--- a/support/doctype/support_ticket/support_ticket.py
+++ b/support/doctype/support_ticket/support_ticket.py
@@ -70,4 +70,11 @@
st = webnotes.bean("Support Ticket", name)
st.doc.status = status
st.save()
-
+
+@webnotes.whitelist()
+def get_tickets():
+ tickets = webnotes.conn.sql("""select name, subject, status from
+ `tabSupport Ticket` where raised_by=%s order by modified desc""",
+ webnotes.session.user, as_dict=1)
+ return tickets
+
diff --git a/website/css/website.css b/website/css/website.css
index dc5b967..25e2c91 100644
--- a/website/css/website.css
+++ b/website/css/website.css
@@ -2,11 +2,10 @@
padding: 30px;
margin: 30px -30px 10px -30px;
min-height: 400px;
- overflow: hidden;
}
.outer .navbar {
- margin: -30px -30px 10px -30px;
+ margin: -30px -30px 20px -30px;
}
footer {
diff --git a/website/helpers/account.py b/website/helpers/account.py
deleted file mode 100644
index 2bab370..0000000
--- a/website/helpers/account.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) 2012 Web Notes Technologies Pvt Ltd.
-# License: GNU General Public License (v3). For more information see license.txt
-
-from __future__ import unicode_literals
-
-import webnotes
-from webnotes.utils import cstr
-
-@webnotes.whitelist()
-def get_orders():
- # find customer id
- customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user},
- "customer")
-
- if customer:
- orders = webnotes.conn.sql("""select name, creation, currency from `tabSales Order`
- where customer=%s""", customer, as_dict=1)
- for order in orders:
- order.items = webnotes.conn.sql("""select item_name, qty, export_rate, delivered_qty
- from `tabSales Order Item` where parent=%s order by idx""", order.name, as_dict=1)
- return orders
- else:
- return []
\ No newline at end of file
diff --git a/website/templates/html/base.html b/website/templates/html/base.html
index 2719f8d..6889d67 100644
--- a/website/templates/html/base.html
+++ b/website/templates/html/base.html
@@ -10,21 +10,18 @@
<script type="text/javascript" src="js/wn-web.js"></script>
<link type="text/css" rel="stylesheet" href="css/all-web.css">
<link type="text/css" rel="stylesheet" href="css/wn-web.css">
-
- {% if favicon %}
+ {%- if favicon %}
<link rel="shortcut icon" href="files/{{ favicon }}" type="image/x-icon">
<link rel="icon" href="files/{{ favicon }}" type="image/x-icon">
{% else %}
<link rel="shortcut icon" href="app/images/favicon.ico" type="image/x-icon">
<link rel="icon" href="app/images/favicon.ico" type="image/x-icon">
- {% endif %}
-
- {% if description %}
+ {% endif -%}
+ {% if description -%}
<meta name="description" content="{{ description }}">
- {% endif %}
-
- {% block header %}
- {% endblock %}
+ {%- endif %}
+ {% block header -%}
+ {%- endblock %}
</head>
<body>
{% block body %}
diff --git a/website/templates/html/navbar.html b/website/templates/html/navbar.html
index 4663a2f..55e8094 100644
--- a/website/templates/html/navbar.html
+++ b/website/templates/html/navbar.html
@@ -1,7 +1,6 @@
-<div class="navbar navbar-inverse"
- style="">
+<div class="navbar navbar-inverse" style="">
<div class="navbar-inner">
- {% if brand_html %}<a class="brand" href="index">{{ brand_html }}</a>{% endif %}
+ {%- if brand_html %}<a class="brand" href="index">{{ brand_html }}</a>{% endif -%}
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
@@ -10,42 +9,27 @@
</button>
<div class="nav-collapse collapse">
<ul class="nav">
- {% for page in top_bar_items %}
- {% if not page.parent_label %}
- <li data-label="{{ page.label }}"
- {% if page.child_items %}
- class="dropdown"
- {% endif %}>
- <a href="{{ page.url or '#' }}"
- {% if page.child_items %}
- class="dropdown-toggle"
- onclick="return false;"
- data-toggle="dropdown"
- {% endif %}
- {{ page.target or ''}}>
- {{ page.label }}
- {% if page.child_items %}
- <b class="caret"></b>
- </a>
- <ul class="dropdown-menu">
- {% for child in page.child_items %}
- <li data-label="{{ child.label }}">
- <a {% if child.indent %}
- style="padding-left:
- {{(int(child.indent)+1)*15 }}px"
- {% endif %}
- href="{{ child.url }}" {{ child.target or '' }}>
- {{ child.label }}
- </a>
- </li>
- {% endfor %}
- </ul>
- {% else %}
- </a>
- {% endif %}
- </li>
- {% endif %}
- {% endfor %}
+ {%- for page in top_bar_items -%}
+ {% if not page.parent_label -%}
+ <li data-label="{{ page.label }}" {% if page.child_items %} class="dropdown"{% endif %}>
+ <a href="{{ page.url or '#' }}" {% if page.child_items %} class="dropdown-toggle" onclick="return false;" data-toggle="dropdown"{% endif %} {{ page.target or ''}}>
+ {{ page.label }}
+ {%- if page.child_items -%}
+ <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ {%- for child in page.child_items -%}
+ <li data-label="{{ child.label }}">
+ <a {% if child.indent %} style="padding-left: {{(int(child.indent)+1)*15 }}px"{% endif %} href="{{ child.url }}" {{ child.target or '' }}>{{ child.label }}</a>
+ </li>
+ {%- endfor -%}
+ </ul>
+ {%- else -%}
+ </a>
+ {%- endif -%}
+ </li>
+ {%- endif -%}
+ {%- endfor %}
</ul>
</div>
</div>
diff --git a/website/templates/html/outer.html b/website/templates/html/outer.html
index c46aaa7..624371e 100644
--- a/website/templates/html/outer.html
+++ b/website/templates/html/outer.html
@@ -12,8 +12,8 @@
<div class="outer">
{% include "html/navbar.html" %}
<div class="content row" id="page-{{ name }}" style="display: block;">
- {% block content %}
- {% endblock %}
+ {%- block content -%}
+ {%- endblock -%}
</div>
</div>
</div>
diff --git a/website/templates/html/page.html b/website/templates/html/page.html
index 11d7b0f..9d38cdc 100644
--- a/website/templates/html/page.html
+++ b/website/templates/html/page.html
@@ -1,20 +1,20 @@
{% extends "html/outer.html" %}
-{% block title %}{{ title }}{% endblock %}
+{% block title -%}{{ title }}{%- endblock %}
-{% block header %}
+{% block header -%}
{{ super() }}
<script>
- {% block javascript %}
- {% endblock %}
+ {% block javascript -%}
+ {%- endblock %}
</script>
- {% block css %}
- {% if insert_style %}
+ {% block css -%}
+ {% if insert_style -%}
<style>{{ css }}</style>
- {% endif %}
- {% endblock %}
-{% endblock %}
+ {%- endif %}
+ {%- endblock %}
+{%- endblock -%}
-{% block content %}
+{%- block content -%}
{{ content }}
-{% endblock %}
\ No newline at end of file
+{%- endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/account.html b/website/templates/pages/account.html
index 9724651..8e8f4b4 100644
--- a/website/templates/pages/account.html
+++ b/website/templates/pages/account.html
@@ -4,62 +4,15 @@
{% block content %}
<div class="span12">
- <p class="pull-right"><a href="profile">Change my name, password</a></p>
- <h3>My Orders</h3>
- <div id="order-list">
- <div class="progress progress-striped active">
- <div class="bar" style="width: 100%;"></div>
- </div>
- </div>
- <hr>
- <h3>My Tickets</h3>
- <div id="ticket-list">
- <div class="progress progress-striped active">
- <div class="bar" style="width: 100%;"></div>
- </div>
- </div>
+ <ul class="breadcrumb">
+ <li><a href="index">Home</a> <span class="divider">/</span></li>
+ <li class="active">My Account</li>
+ </ul>
+ <h3>My Account</h3>
+ <p><a href="profile"><i class="icon-user"></i> Change my name, password</a></p>
+ <p><a href="orders"><i class="icon-list"></i> My Orders</a></p>
+ <p><a href="tickets"><i class="icon-tags"></i> My Tickets</a></p>
+ <p><a href="server.py?cmd=web_logout"><i class="icon-signout"></i> Logout</a></p>
+ </ul>
</div>
-<script>
-$(document).ready(function() {
- var order_start = 0,
- ticket_start = 0;
-
- wn.call({
- method: "website.helpers.account.get_orders",
- args: {
- start: order_start
- },
- callback: function(r) {
- $("#order-list .progress").remove();
- var $list = $("#order-list");
-
- if(!(r.message && r.message.length)) {
- $list.html("<div class='alert'>No Orders Yet</div>");
- return;
- }
-
- $.each(r.message, function(i, order) {
-
- // parent
- var $order = $(repl('<div class="row">\
- <div class="span4"><a href="order?id=%(name)s">%(name)s</a></span3>\
- </div>', order)).appendTo($list);
-
- // items
- $.each(order.items || [], function(i, item) {
- var $item = $(repl('<div class="span8">\
- <div class="row">\
- <div class="span4">%(item_name)s</div>\
- <div class="span2">%(export_rate)s</div>\
- <div class="span2">%(status)s</div>\
- </div>\
- </div>', item)).appendTo($order);
- });
-
- $("<hr>").appendTo($order);
- });
- }
- })
-})
-</script>
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/order.html b/website/templates/pages/order.html
new file mode 100644
index 0000000..b8d9695
--- /dev/null
+++ b/website/templates/pages/order.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Print Format</title>
+ <meta name="generator" content="wnframework">
+</head>
+<body>
+ {{ webnotes.form_dict }}
+</body>
+</html>
\ No newline at end of file
diff --git a/website/templates/pages/orders.html b/website/templates/pages/orders.html
new file mode 100644
index 0000000..1a1cc37
--- /dev/null
+++ b/website/templates/pages/orders.html
@@ -0,0 +1,62 @@
+{% extends "html/page.html" %}
+
+{% set title="My Orders" %}
+
+{% block content %}
+<div class="span12">
+ <ul class="breadcrumb">
+ <li><a href="index">Home</a> <span class="divider">/</span></li>
+ <li><a href="account">My Account</a> <span class="divider">/</span></li>
+ <li class="active">My Orders</li>
+ </ul>
+ <h3><i class="icon-list"></i> My Orders</h3>
+ <hr>
+ <div id="order-list" style="font-size: 13px;">
+ <div class="progress progress-striped active">
+ <div class="bar" style="width: 100%;"></div>
+ </div>
+ </div>
+</div>
+<script>
+$(document).ready(function() {
+ var order_start = 0;
+
+ wn.call({
+ method: "selling.doctype.sales_order.sales_order.get_orders",
+ args: {
+ start: order_start
+ },
+ callback: function(r) {
+ $("#order-list .progress").remove();
+ var $list = $("#order-list");
+
+ if(!(r.message && r.message.length)) {
+ $list.html("<div class='alert'>No Orders Yet</div>");
+ return;
+ }
+
+ $.each(r.message, function(i, order) {
+
+ // parent
+ var $order = $(repl('<div class="row">\
+ <div class="span4"><a href="order?id=%(name)s">%(name)s</a></span3>\
+ </div>', order)).appendTo($list);
+
+ // items
+ $.each(order.items || [], function(i, item) {
+ var $item = $(repl('<div class="span8">\
+ <div class="row">\
+ <div class="span4">%(item_name)s</div>\
+ <div class="span2">%(export_rate)s</div>\
+ <div class="span2">%(status)s</div>\
+ </div>\
+ </div>', item)).appendTo($order);
+ });
+
+ $("<hr>").appendTo($list);
+ });
+ }
+ })
+})
+</script>
+{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/print.html b/website/templates/pages/print.html
index a8decdf..b684dfe 100644
--- a/website/templates/pages/print.html
+++ b/website/templates/pages/print.html
@@ -4,9 +4,15 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Print Format</title>
- <meta name="generator" content="wnframework">
+ <meta name="generator" content="wnframework">
+ <style>
+ {{ css }}
+ </style>
</head>
<body>
{{ body }}
</body>
+{%- if comment -%}
+<!-- {{ comment }} -->
+{%- endif -%}
</html>
\ No newline at end of file
diff --git a/website/templates/pages/profile.html b/website/templates/pages/profile.html
index d0d4059..1b9350c 100644
--- a/website/templates/pages/profile.html
+++ b/website/templates/pages/profile.html
@@ -3,8 +3,13 @@
{% set title="My Profile" %}
{% block content %}
-<div class="span9">
- <h2>My Profile</h2>
+<div class="span12">
+ <ul class="breadcrumb">
+ <li><a href="index">Home</a> <span class="divider">/</span></li>
+ <li><a href="account">My Account</a> <span class="divider">/</span></li>
+ <li class="active">My Profile</li>
+ </ul>
+ <h2><i class="icon-user"></i> My Profile</h2>
<hr>
<div class="alert" id="message" style="display: none;"></div>
<form class="form-horizontal">
diff --git a/website/templates/pages/tickets.html b/website/templates/pages/tickets.html
new file mode 100644
index 0000000..822cd04
--- /dev/null
+++ b/website/templates/pages/tickets.html
@@ -0,0 +1,53 @@
+{% extends "html/page.html" %}
+
+{% set title="My Orders" %}
+
+{% block content %}
+<div class="span12">
+ <ul class="breadcrumb">
+ <li><a href="index">Home</a> <span class="divider">/</span></li>
+ <li><a href="account">My Account</a> <span class="divider">/</span></li>
+ <li class="active">My Tickets</li>
+ </ul>
+ <h3><i class="icon-tags"></i> My Tickets</h3>
+ <hr>
+ <div id="ticket-list" style="font-size: 13px;">
+ <div class="progress progress-striped active">
+ <div class="bar" style="width: 100%;"></div>
+ </div>
+ </div>
+</div>
+<script>
+$(document).ready(function() {
+ var order_start = 0;
+
+ wn.call({
+ method: "support.doctype.support_ticket.support_ticket.get_tickets",
+ args: {
+ start: order_start
+ },
+ callback: function(r) {
+ $("#ticket-list .progress").remove();
+ var $list = $("#ticket-list");
+
+ if(!(r.message && r.message.length)) {
+ $list.html("<div class='alert'>No Tickets Yet</div>");
+ return;
+ }
+
+ $.each(r.message, function(i, ticket) {
+
+ // parent
+ var $ticket = $(repl('<div class="row">\
+ <div class="span2"><span class="label">%(status)s</span></div>\
+ <div class="span3"><a href="ticket?id=%(name)s">%(name)s</a></div>\
+ <div class="span7">%(subject)s</div>\
+ </div>', ticket)).appendTo($list);
+
+ $("<hr>").appendTo($list);
+ });
+ }
+ })
+})
+</script>
+{% endblock %}
\ No newline at end of file
diff --git a/website/utils.py b/website/utils.py
index 811a40d..b059bea 100644
--- a/website/utils.py
+++ b/website/utils.py
@@ -76,7 +76,10 @@
from_cache = True
if not html:
- webnotes.connect()
+ from webnotes.auth import HTTPRequest
+ webnotes.http_request = HTTPRequest()
+
+ #webnotes.connect()
html = load_into_cache(page_name)
from_cache = False