Merge branch 'master' into edge

This commit is contained in:
Anand Doshi 2013-02-16 11:11:14 +05:30
commit c79cd76746
68 changed files with 356 additions and 1324 deletions

View File

@ -69,6 +69,10 @@
<td><a href="https://github.com/mleibman/SlickGrid">SlickGrid</a></td>
<td>A lightning fast JavaScript grid/spreadsheet.</td>
</tr>
<tr>
<td><a href="http://arshaw.com/fullcalendar/">FullCalendar</a></td>
<td>FullCalendar is a jQuery plugin that provides a full-sized, drag and drop calendar.</td>
</tr>
<tr>
<td><a href="http://www.flotcharts.org/">Flot Charting Library</a></td>
<td>Attractive JavaScript plotting for jQuery.</td>
@ -85,6 +89,10 @@
<td><a href="http://jscolor.com/">JSColor - Color Picker</a></td>
<td>HTML/Javascript Color Picker.</td>
</tr>
<tr>
<td><a href="http://qunitjs.com/">QUnit</a></td>
<td>A JavaScript Unit Testing framework.</td>
</tr>
<tr>
<td><a href="https://github.com/dcneiner/Downloadify">Downloadify - Flash Download Widget</a></td>
<td>A tiny javascript + Flash library that enables the creation and download of text files without server interaction.</td>

View File

@ -1,4 +1,8 @@
erpnext.updates = [
["15th February, 2013", [
"Calendar: Added new FullCalendar, and Calendar Views",
"Leave Application: Added email notifications on Leave Application",
]],
["13th February, 2013", [
"Employee: If Employee is linked to a Profile, copy Full Name, Date of Birth, \
Image and Gender to Profile",
@ -8,7 +12,7 @@ erpnext.updates = [
"Bookmarks: Add bookmarks via toolbar by clicking on the <i class='icon-star'></i> sign.",
]],
["5th February, 2013", [
"Holiday Block List: Block users from taking leave on certain days.",
"Leave Block List: Block users from taking leave on certain days.",
]],
["2nd February, 2013", [
"Warehouse: Added table Warehouse User to restrict Warehouse Entry per user.",

View File

@ -1,8 +1,8 @@
[
{
"creation": "2013-01-10 16:34:13",
"creation": "2013-02-05 11:48:26",
"docstatus": 0,
"modified": "2013-02-04 15:34:55",
"modified": "2013-02-14 17:21:51",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -60,10 +60,10 @@
{
"description": "Days for which Holidays are blocked for this department.",
"doctype": "DocField",
"fieldname": "holiday_block_list",
"fieldname": "leave_block_list",
"fieldtype": "Link",
"label": "Holiday Block List",
"options": "Holiday Block List"
"label": "Leave Block List",
"options": "Leave Block List"
},
{
"doctype": "DocPerm",

View File

@ -1,5 +1,4 @@
test_records = [
[{"doctype":"Department", "department_name":"_Test Department"}],
[{"doctype":"Department", "department_name":"_Test Department with Block List",
"holiday_block_list": "_Test Holiday Block List"}],
[{"doctype":"Department", "department_name":"_Test Department 1"}]
]

View File

@ -7,7 +7,8 @@ test_records = [[{
"gender": "Female",
"status": "Active",
"company": "_Test Company",
"user_id": "test@example.com"
"user_id": "test@example.com",
"department": "_Test Department"
}],
[{
"doctype":"Employee",
@ -18,7 +19,8 @@ test_records = [[{
"gender": "Male",
"status": "Active",
"company": "_Test Company",
"user_id": "test1@example.com"
"user_id": "test1@example.com",
"department": "_Test Department 1"
}],
[{
"doctype":"Employee",
@ -29,6 +31,7 @@ test_records = [[{
"gender": "Male",
"status": "Active",
"company": "_Test Company",
"user_id": "test2@example.com"
"user_id": "test2@example.com",
"department": "_Test Department 1"
}]
]

View File

@ -1,22 +0,0 @@
# For license information, please see license.txt
from __future__ import unicode_literals
import webnotes
from accounts.utils import validate_fiscal_year
from webnotes import _
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
def validate(self):
dates = []
for d in self.doclist.get({"doctype":"Holiday Block List Date"}):
# validate fiscal year
validate_fiscal_year(d.block_date, self.doc.year, _("Block Date"))
# date is not repeated
if d.block_date in dates:
webnotes.msgprint(_("Date is repeated") + ":" + d.block_date, raise_exception=1)
dates.append(d.block_date)

View File

@ -1,16 +0,0 @@
[
"Allow Users",
"Block Holidays on important days.",
"Block Days",
"HR",
"Company",
"Holiday Block List Allowed",
"Holiday Block List Dates",
"Holiday Block List",
"Stop users from making Leave Applications on following days.",
"Applies to Company",
"Holiday Block List Name",
"Year",
"If not checked, the list will have to be added to each Department where it has to be applied.",
"Allow the following users to make Leave Applications for block days."
]

View File

@ -1,4 +0,0 @@
[
"Date is repeated",
"Block Date"
]

View File

@ -1,16 +0,0 @@
{
"Allow Users": "\u0627\u0644\u0633\u0645\u0627\u062d \u0644\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646",
"Allow the following users to make Leave Applications for block days.": "\u062a\u0633\u0645\u062d \u0644\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646 \u0627\u0644\u062a\u0627\u0644\u064a\u0629 \u0644\u062c\u0639\u0644 \u062a\u0637\u0628\u064a\u0642\u0627\u062a \u0625\u062c\u0627\u0632\u0629 \u0644\u0639\u062f\u0629 \u0623\u064a\u0627\u0645 \u0643\u062a\u0644\u0629.",
"Applies to Company": "\u064a\u0646\u0637\u0628\u0642 \u0639\u0644\u0649 \u0634\u0631\u0643\u0629",
"Block Days": "\u0643\u062a\u0644\u0629 \u0623\u064a\u0627\u0645",
"Block Holidays on important days.": "\u0645\u0646\u0639 \u0627\u0644\u0625\u062c\u0627\u0632\u0627\u062a \u0641\u064a \u0627\u0644\u0623\u064a\u0627\u0645 \u0627\u0644\u0647\u0627\u0645\u0629.",
"Company": "\u0634\u0631\u0643\u0629",
"HR": "HR",
"Holiday Block List": "\u0625\u0642\u0627\u0645\u0627\u062a \u0642\u0627\u0626\u0645\u0629",
"Holiday Block List Allowed": "\u0639\u0637\u0644\u0629 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062d\u0638\u0631 \u0645\u0633\u0645\u0648\u062d",
"Holiday Block List Dates": "\u0645\u0648\u0627\u0639\u064a\u062f \u0625\u0642\u0627\u0645\u0627\u062a \u0642\u0627\u0626\u0645\u0629",
"Holiday Block List Name": "\u0627\u0633\u0645 \u0625\u0642\u0627\u0645\u0627\u062a \u0642\u0627\u0626\u0645\u0629",
"If not checked, the list will have to be added to each Department where it has to be applied.": "\u0625\u0646 \u0644\u0645 \u064a\u0643\u0646 \u062a\u0645\u060c \u0633\u064a\u0643\u0648\u0646 \u0644\u062f\u064a\u0643 \u0642\u0627\u0626\u0645\u0629 \u062a\u0636\u0627\u0641 \u0625\u0644\u0649 \u0643\u0644 \u0642\u0633\u0645 \u062d\u064a\u062b \u0623\u0646\u0647 \u0644\u0627 \u0628\u062f \u0645\u0646 \u062a\u0637\u0628\u064a\u0642\u0647\u0627.",
"Stop users from making Leave Applications on following days.": "\u0648\u0642\u0641 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646 \u0645\u0646 \u0625\u062c\u0631\u0627\u0621 \u062a\u0637\u0628\u064a\u0642\u0627\u062a \u0639\u0644\u0649 \u0625\u062c\u0627\u0632\u0629 \u0627\u0644\u0623\u064a\u0627\u0645 \u0627\u0644\u062a\u0627\u0644\u064a\u0629.",
"Year": "\u0639\u0627\u0645"
}

View File

@ -1,4 +0,0 @@
{
"Block Date": "\u0645\u0646\u0639 \u062a\u0627\u0631\u064a\u062e",
"Date is repeated": "\u0648\u064a\u062a\u0643\u0631\u0631 \u0627\u0644\u062a\u0627\u0631\u064a\u062e"
}

View File

@ -1,16 +0,0 @@
{
"Allow Users": "Permitir que los usuarios",
"Allow the following users to make Leave Applications for block days.": "Permitir a los usuarios realizar las siguientes aplicaciones dejan para los d\u00edas de bloque.",
"Applies to Company": "Corresponde a la Empresa",
"Block Days": "D\u00edas de bloque",
"Block Holidays on important days.": "Bloque Vacaciones en d\u00edas importantes.",
"Company": "Empresa",
"HR": "HR",
"Holiday Block List": "Holiday lista de bloqueo",
"Holiday Block List Allowed": "Holiday Lista de bloqueo animales",
"Holiday Block List Dates": "Las fechas de vacaciones de listas de bloqueo",
"Holiday Block List Name": "Bloque de vacaciones Lista de Nombres",
"If not checked, the list will have to be added to each Department where it has to be applied.": "Si no est\u00e1 activada, la lista tendr\u00e1 que ser a\u00f1adido a cada Departamento donde se ha de aplicar.",
"Stop users from making Leave Applications on following days.": "Deje que los usuarios realicen aplicaciones dejan en los d\u00edas siguientes.",
"Year": "A\u00f1o"
}

View File

@ -1,4 +0,0 @@
{
"Block Date": "Bloque Fecha",
"Date is repeated": "La fecha se repite"
}

View File

@ -1,16 +0,0 @@
{
"Allow Users": "Autoriser les utilisateurs",
"Allow the following users to make Leave Applications for block days.": "Autoriser les utilisateurs suivants pour faire demandes d&#39;autorisation pour les jours de bloc.",
"Applies to Company": "S&#39;applique \u00e0 l&#39;entreprise",
"Block Days": "Bloquer les jours",
"Block Holidays on important days.": "Bloquer les jours f\u00e9ri\u00e9s importants.",
"Company": "Entreprise",
"HR": "RH",
"Holiday Block List": "Block List vacances",
"Holiday Block List Allowed": "Block List vacances accept\u00e9s",
"Holiday Block List Dates": "Dates de vacances de listes rouges d&#39;",
"Holiday Block List Name": "Nom de la liste de vacances Bloquer",
"If not checked, the list will have to be added to each Department where it has to be applied.": "Si ce n&#39;est pas coch\u00e9e, la liste devra \u00eatre ajout\u00e9 \u00e0 chaque d\u00e9partement o\u00f9 il doit \u00eatre appliqu\u00e9.",
"Stop users from making Leave Applications on following days.": "Emp\u00eacher les utilisateurs de faire des demandes d&#39;autorisation, les jours suivants.",
"Year": "Ann\u00e9e"
}

View File

@ -1,4 +0,0 @@
{
"Block Date": "Date de bloquer",
"Date is repeated": "La date est r\u00e9p\u00e9t\u00e9e"
}

View File

@ -1,16 +0,0 @@
{
"Allow Users": "\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e\u0913\u0902 \u0915\u094b \u0905\u0928\u0941\u092e\u0924\u093f \u0926\u0947\u0902",
"Allow the following users to make Leave Applications for block days.": "\u0928\u093f\u092e\u094d\u0928 \u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e\u0913\u0902 \u0915\u094b \u092c\u094d\u0932\u0949\u0915 \u0926\u093f\u0928\u094b\u0902 \u0915\u0947 \u0932\u093f\u090f \u091b\u0941\u091f\u094d\u091f\u0940 \u0905\u0928\u0941\u092a\u094d\u0930\u092f\u094b\u0917 \u092c\u0928\u093e\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f \u0905\u0928\u0941\u092e\u0924\u093f \u0926\u0947\u0902.",
"Applies to Company": "\u0915\u0902\u092a\u0928\u0940 \u0915\u0947 \u0932\u093f\u090f \u0932\u093e\u0917\u0942 \u0939\u094b\u0924\u093e \u0939\u0948",
"Block Days": "\u092c\u094d\u0932\u0949\u0915 \u0926\u093f\u0928",
"Block Holidays on important days.": "\u092e\u0939\u0924\u094d\u0935\u092a\u0942\u0930\u094d\u0923 \u0926\u093f\u0928 \u092a\u0930 \u091b\u0941\u091f\u094d\u091f\u093f\u092f\u093e\u0901 \u092e\u0948.",
"Company": "\u0915\u0902\u092a\u0928\u0940",
"HR": "\u092e\u093e\u0928\u0935 \u0938\u0902\u0938\u093e\u0927\u0928",
"Holiday Block List": "\u0905\u0935\u0915\u093e\u0936 \u092c\u094d\u0932\u0949\u0915 \u0938\u0942\u091a\u0940",
"Holiday Block List Allowed": "\u0905\u0935\u0915\u093e\u0936 \u0938\u0942\u091a\u0940 \u092c\u094d\u0932\u0949\u0915 \u0930\u0916 \u0938\u0915\u0924\u0947 \u0939\u0948",
"Holiday Block List Dates": "\u0905\u0935\u0915\u093e\u0936 \u092c\u094d\u0932\u0949\u0915 \u0938\u0942\u091a\u0940 \u0924\u093f\u0925\u093f\u092f\u093e\u0902",
"Holiday Block List Name": "\u0905\u0935\u0915\u093e\u0936 \u092c\u094d\u0932\u0949\u0915 \u0938\u0942\u091a\u0940 \u092e\u0947\u0902 \u0928\u093e\u092e",
"If not checked, the list will have to be added to each Department where it has to be applied.": "\u0905\u0917\u0930 \u091c\u093e\u0901\u091a \u0928\u0939\u0940\u0902 \u0915\u093f\u092f\u093e \u0917\u092f\u093e \u0939\u0948, \u0907\u0938 \u0938\u0942\u091a\u0940 \u0915\u0947 \u0932\u093f\u090f \u092a\u094d\u0930\u0924\u094d\u092f\u0947\u0915 \u0935\u093f\u092d\u093e\u0917 \u0939\u0948 \u091c\u0939\u093e\u0902 \u0907\u0938\u0947 \u0932\u093e\u0917\u0942 \u0915\u093f\u092f\u093e \u0917\u092f\u093e \u0939\u0948 \u0915\u0947 \u0932\u093f\u090f \u091c\u094b\u0921\u093c\u093e \u091c\u093e \u0939\u094b\u0917\u093e.",
"Stop users from making Leave Applications on following days.": "\u0928\u093f\u092e\u094d\u0928\u0932\u093f\u0916\u093f\u0924 \u0926\u093f\u0928 \u092a\u0930 \u091b\u0941\u091f\u094d\u091f\u0940 \u0905\u0928\u0941\u092a\u094d\u0930\u092f\u094b\u0917 \u092c\u0928\u093e\u0928\u0947 \u0938\u0947 \u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e\u0913\u0902 \u0915\u094b \u092c\u0902\u0926 \u0915\u0930\u094b.",
"Year": "\u0935\u0930\u094d\u0937"
}

View File

@ -1,4 +0,0 @@
{
"Block Date": "\u0924\u093f\u0925\u093f \u092c\u094d\u0932\u0949\u0915",
"Date is repeated": "\u0924\u093f\u0925\u093f \u0926\u094b\u0939\u0930\u093e\u092f\u093e \u0939\u0948"
}

View File

@ -1,16 +0,0 @@
{
"Allow Users": "Omogu\u0107iti korisnicima",
"Allow the following users to make Leave Applications for block days.": "Dopusti sljede\u0107i korisnicima da ostavite Prijave za blok dana.",
"Applies to Company": "Odnosi se na Dru\u0161tvo",
"Block Days": "Blok Dani",
"Block Holidays on important days.": "Blok Odmor o va\u017enim dana.",
"Company": "Dru\u0161tvo",
"HR": "HR",
"Holiday Block List": "Turisti\u010dka Blok Popis",
"Holiday Block List Allowed": "Turisti\u010dka Blok Popis dopu\u0161tenih",
"Holiday Block List Dates": "Holiday Block List datumi",
"Holiday Block List Name": "Turisti\u010dka Blok Popis Ime",
"If not checked, the list will have to be added to each Department where it has to be applied.": "Ako nije ozna\u010deno, popis \u0107e biti dodan u svakom odjela gdje se mora primjenjivati.",
"Stop users from making Leave Applications on following days.": "Prestani korisnike od izrade ostaviti aplikacija na sljede\u0107im danima.",
"Year": "Godina"
}

View File

@ -1,4 +0,0 @@
{
"Block Date": "Blok Datum",
"Date is repeated": "Datum se ponavlja"
}

View File

@ -1,16 +0,0 @@
{
"Allow Users": "Gebruikers toestaan",
"Allow the following users to make Leave Applications for block days.": "Laat de volgende gebruikers te vertrekken Toepassingen maken voor blok dagen.",
"Applies to Company": "Geldt voor Bedrijf",
"Block Days": "Blokkeren Dagen",
"Block Holidays on important days.": "Blok Vakantie op belangrijke dagen.",
"Company": "Vennootschap",
"HR": "HR",
"Holiday Block List": "Holiday Block List",
"Holiday Block List Allowed": "Holiday toegestaan \u200b\u200bBlock List",
"Holiday Block List Dates": "Holiday Block List Data",
"Holiday Block List Name": "Holiday Block List Name",
"If not checked, the list will have to be added to each Department where it has to be applied.": "Indien niet gecontroleerd, wordt de lijst worden toegevoegd aan elk Department waar het moet worden toegepast.",
"Stop users from making Leave Applications on following days.": "Stop gebruikers van het maken van verlofaanvragen op de volgende dagen.",
"Year": "Jaar"
}

View File

@ -1,4 +0,0 @@
{
"Block Date": "Blokkeren Datum",
"Date is repeated": "Datum wordt herhaald"
}

View File

@ -1,16 +0,0 @@
{
"Allow Users": "Permitir que os usu\u00e1rios",
"Allow the following users to make Leave Applications for block days.": "Permitir que os usu\u00e1rios a seguir para fazer aplica\u00e7\u00f5es deixam para os dias de bloco.",
"Applies to Company": "Aplica-se a Empresa",
"Block Days": "Dias bloco",
"Block Holidays on important days.": "Bloquear feriados em dias importantes.",
"Company": "Companhia",
"HR": "HR",
"Holiday Block List": "Lista de Bloqueios de f\u00e9rias",
"Holiday Block List Allowed": "Lista de feriado Bloco admitidos",
"Holiday Block List Dates": "Datas de f\u00e9rias Lista de Bloqueios",
"Holiday Block List Name": "Nome de f\u00e9rias Lista de Bloqueios",
"If not checked, the list will have to be added to each Department where it has to be applied.": "Se n\u00e3o for controlada, a lista dever\u00e1 ser adicionado a cada departamento onde tem de ser aplicado.",
"Stop users from making Leave Applications on following days.": "Pare de usu\u00e1rios de fazer aplica\u00e7\u00f5es deixam nos dias seguintes.",
"Year": "Ano"
}

View File

@ -1,4 +0,0 @@
{
"Block Date": "Bloquear Data",
"Date is repeated": "Data \u00e9 repetido"
}

View File

@ -1,20 +0,0 @@
test_records = [[{
"doctype":"Holiday Block List",
"holiday_block_list_name": "_Test Holiday Block List",
"year": "_Test Fiscal Year 2013",
"company": "_Test Company"
}, {
"doctype": "Holiday Block List Date",
"parent": "_Test Holiday Block List",
"parenttype": "Holiday Block List",
"parentfield": "holiday_block_list_dates",
"block_date": "2013-01-02",
"reason": "First work day"
}, {
"doctype": "Holiday Block List Allow",
"parent": "_Test Holiday Block List",
"parenttype": "Holiday Block List",
"parentfield": "holiday_block_list_allowed",
"allow_user": "test1@example.com",
}
]]

View File

@ -1,5 +0,0 @@
[
"HR",
"Allow User",
"Holiday Block List Allow"
]

View File

@ -1,5 +0,0 @@
{
"Allow User": "\u062a\u0633\u0645\u062d \u0644\u0644\u0645\u0633\u062a\u062e\u062f\u0645",
"HR": "HR",
"Holiday Block List Allow": "\u0639\u0637\u0644\u0629 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062d\u0638\u0631 \u0627\u0644\u0633\u0645\u0627\u062d"
}

View File

@ -1,5 +0,0 @@
{
"Allow User": "Permitir al usuario",
"HR": "HR",
"Holiday Block List Allow": "Lista Casas Bloquear Permitir"
}

View File

@ -1,5 +0,0 @@
{
"Allow User": "Permettre \u00e0 l&#39;utilisateur",
"HR": "RH",
"Holiday Block List Allow": "Block List vacances Permettez-"
}

View File

@ -1,5 +0,0 @@
{
"Allow User": "\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e \u0915\u0940 \u0905\u0928\u0941\u092e\u0924\u093f",
"HR": "\u092e\u093e\u0928\u0935 \u0938\u0902\u0938\u093e\u0927\u0928",
"Holiday Block List Allow": "\u0905\u0935\u0915\u093e\u0936 \u092c\u094d\u0932\u0949\u0915 \u0938\u0942\u091a\u0940 \u0915\u0940 \u0905\u0928\u0941\u092e\u0924\u093f \u0926\u0947\u0902"
}

View File

@ -1,5 +0,0 @@
{
"Allow User": "Dopusti korisnika",
"HR": "HR",
"Holiday Block List Allow": "Turisti\u010dka Popis Blok Dopustite"
}

View File

@ -1,5 +0,0 @@
{
"Allow User": "Door gebruiker toestaan",
"HR": "HR",
"Holiday Block List Allow": "Holiday Block List Laat"
}

View File

@ -1,5 +0,0 @@
{
"Allow User": "Permitir que o usu\u00e1rio",
"HR": "HR",
"Holiday Block List Allow": "Lista de Bloqueios de f\u00e9rias Permitir"
}

View File

@ -1,6 +0,0 @@
[
"HR",
"Reason",
"Holiday Block List Date",
"Block Date"
]

View File

@ -1,6 +0,0 @@
{
"Block Date": "\u0645\u0646\u0639 \u062a\u0627\u0631\u064a\u062e",
"HR": "HR",
"Holiday Block List Date": "\u062a\u0627\u0631\u064a\u062e \u0625\u0642\u0627\u0645\u0627\u062a \u0642\u0627\u0626\u0645\u0629",
"Reason": "\u0633\u0628\u0628"
}

View File

@ -1,6 +0,0 @@
{
"Block Date": "Bloque Fecha",
"HR": "HR",
"Holiday Block List Date": "Bloque de vacaciones Lista Fecha",
"Reason": "Raz\u00f3n"
}

View File

@ -1,6 +0,0 @@
{
"Block Date": "Date de bloquer",
"HR": "RH",
"Holiday Block List Date": "Liste Date vacances Bloquer",
"Reason": "Raison"
}

View File

@ -1,6 +0,0 @@
{
"Block Date": "\u0924\u093f\u0925\u093f \u092c\u094d\u0932\u0949\u0915",
"HR": "\u092e\u093e\u0928\u0935 \u0938\u0902\u0938\u093e\u0927\u0928",
"Holiday Block List Date": "\u0905\u0935\u0915\u093e\u0936 \u092c\u094d\u0932\u0949\u0915 \u0938\u0942\u091a\u0940 \u0924\u093f\u0925\u093f",
"Reason": "\u0915\u093e\u0930\u0923"
}

View File

@ -1,6 +0,0 @@
{
"Block Date": "Blok Datum",
"HR": "HR",
"Holiday Block List Date": "Turisti\u010dka Blok Popis Datum",
"Reason": "Razlog"
}

View File

@ -1,6 +0,0 @@
{
"Block Date": "Blokkeren Datum",
"HR": "HR",
"Holiday Block List Date": "Holiday Block List Datum",
"Reason": "Reden"
}

View File

@ -1,6 +0,0 @@
{
"Block Date": "Bloquear Data",
"HR": "HR",
"Holiday Block List Date": "Data feriado Lista de Bloqueios",
"Reason": "Raz\u00e3o"
}

View File

@ -18,19 +18,19 @@ from __future__ import unicode_literals
import webnotes
from webnotes import _
from webnotes.utils import cint, cstr, date_diff, flt, formatdate, getdate
from webnotes.model import db_exists
from webnotes.model.wrapper import copy_doclist
from webnotes import form, msgprint
import datetime
from webnotes.utils import cint, cstr, date_diff, flt, formatdate, getdate, get_url_to_form, get_fullname
from webnotes import msgprint
from webnotes.utils.email_lib import sendmail
class LeaveDayBlockedError(Exception): pass
class DocType:
def __init__(self, doc, doclist):
self.doc = doc
self.doclist = doclist
from webnotes.model.controller import DocListController
class DocType(DocListController):
def setup(self):
if webnotes.conn.exists(self.doc.doctype, self.doc.name):
self.previous_doc = webnotes.doc(self.doc.doctype, self.doc.name)
else:
self.previous_doc = None
def validate(self):
# if self.doc.leave_approver == self.doc.owner:
@ -40,51 +40,41 @@ class DocType:
self.validate_max_days()
self.validate_block_days()
def on_update(self):
if (not self.previous_doc and self.doc.leave_approver) or (self.doc.status == "Open" \
and self.previous_doc.leave_approver != self.doc.leave_approver):
# notify leave approver about creation
self.notify_leave_approver()
elif self.previous_doc and \
self.previous_doc.status == "Open" and self.doc.status == "Rejected":
# notify employee about rejection
self.notify_employee(self.doc.status)
def on_submit(self):
if self.doc.status != "Approved":
webnotes.msgprint("""Only Leave Applications with status 'Approved' can be Submitted.""",
raise_exception=True)
# notify leave applier about approval
self.notify_employee(self.doc.status)
def on_cancel(self):
# notify leave applier about cancellation
self.notify_employee("cancelled")
def validate_block_days(self):
for block_list in self.get_applicable_block_lists():
self.check_block_dates(block_list)
from hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
def get_applicable_block_lists(self):
block_lists = []
def add_block_list(block_list):
if block_list:
if not self.is_user_in_allow_list(block_list):
block_lists.append(block_list)
block_dates = get_applicable_block_dates(self.doc.from_date, self.doc.to_date,
self.doc.employee, self.doc.company)
# per department
department = webnotes.conn.get_value("Employee", self.doc.employee, "department")
if department:
block_list = webnotes.conn.get_value("Department", department, "holiday_block_list")
add_block_list(block_list)
if block_dates:
webnotes.msgprint(_("Following dates are blocked for Leave") + ":")
for d in block_dates:
webnotes.msgprint(formatdate(d.block_date) + ": " + d.reason)
# global
for block_list in webnotes.conn.sql_list("""select name from `tabHoliday Block List`
where ifnull(applies_to_all_departments,0)=1 and company=%s""", self.doc.company):
add_block_list(block_list)
return block_lists
def check_block_dates(self, block_list):
from_date = getdate(self.doc.from_date)
to_date = getdate(self.doc.to_date)
for d in webnotes.conn.sql("""select block_date, reason from
`tabHoliday Block List Date` where parent=%s""", block_list, as_dict=1):
block_date = getdate(d.block_date)
if block_date > from_date and block_date < to_date:
webnotes.msgprint(_("You cannot apply for a leave on the following date because it is blocked")
+ ": " + formatdate(d.block_date) + _(" Reason: ") + d.reason)
if self.doc.docstatus == 1:
# throw exception only when submitting
raise LeaveDayBlockedError
def is_user_in_allow_list(self, block_list):
return webnotes.session.user in webnotes.conn.sql_list("""select allow_user
from `tabHoliday Block List Allow` where parent=%s""", block_list)
if self.doc.docstatus == 1:
raise LeaveDayBlockedError
def get_holidays(self):
tot_hol = webnotes.conn.sql("""select count(*) from `tabHoliday` h1, `tabHoliday List` h2, `tabEmployee` e1
@ -149,6 +139,53 @@ class DocType:
msgprint("Sorry ! You cannot apply for %s for more than %s days" % (self.doc.leave_type, max_days))
raise Exception
def notify_employee(self, status):
employee = webnotes.doc("Employee", self.doc.employee)
if not employee.user_id:
return
def _get_message(url=False):
if url:
name = get_url_to_form(self.doc.doctype, self.doc.name)
else:
name = self.doc.name
return (_("Leave Application") + ": %s - %s") % (name, _(status))
self.notify({
# for post in messages
"message": _get_message(url=True),
"message_to": employee.user_id,
"subject": _get_message(),
})
def notify_leave_approver(self):
employee = webnotes.doc("Employee", self.doc.employee)
def _get_message(url=False):
name = self.doc.name
employee_name = get_fullname(employee.user_id)
if url:
name = get_url_to_form(self.doc.doctype, self.doc.name)
employee_name = get_url_to_form("Employee", self.doc.employee, label=employee_name)
return (_("New Leave Application") + ": %s - " + _("Employee") + ": %s") % (name, employee_name)
self.notify({
# for post in messages
"message": _get_message(url=True),
"message_to": self.doc.leave_approver,
# for email
"subject": _get_message()
})
def notify(self, args):
args = webnotes._dict(args)
from utilities.page.messages.messages import post
post({"txt": args.message, "contact": args.message_to, "subject": args.subject,
"notify": True})
@webnotes.whitelist()
def get_leave_balance(employee, leave_type, fiscal_year):
@ -180,3 +217,59 @@ def get_approver_list():
def is_lwp(leave_type):
lwp = webnotes.conn.sql("select is_lwp from `tabLeave Type` where name = %s", leave_type)
return lwp and cint(lwp[0][0]) or 0
@webnotes.whitelist()
def get_events(start, end):
events = []
employee = webnotes.conn.get_default("employee", webnotes.session.user)
company = webnotes.conn.get_default("company", webnotes.session.user)
add_department_leaves(events, start, end, employee, company)
add_block_dates(events, start, end, employee, company)
return events
def add_department_leaves(events, start, end, employee, company):
department = webnotes.conn.get_value("Employee", employee, "department")
if not department:
return
# department leaves
department_employees = webnotes.conn.sql_list("select name from tabEmployee where department=%s",
department)
for d in webnotes.conn.sql("""select name, from_date, to_date, employee_name, half_day,
status, employee
from `tabLeave Application` where
(from_date between %s and %s or to_date between %s and %s)
and docstatus < 2
and status!="Rejected"
and employee in ('%s')""" % ("%s", "%s", "%s", "%s", "', '".join(department_employees)),
(start, end, start, end), as_dict=True):
events.append({
"name": d.name,
"doctype": "Leave Application",
"from_date": d.from_date,
"to_date": d.to_date,
"status": d.status,
"title": _("Leave by") + " " + d.employee_name + \
(d.half_day and _(" (Half Day)") or "")
})
def add_block_dates(events, start, end, employee, company):
# block days
from hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
cnt = 0
block_dates = get_applicable_block_dates(start, end, employee, company, all_lists=True)
for block_date in block_dates:
events.append({
"doctype": "Leave Block List Date",
"from_date": block_date.block_date,
"title": _("Leave Blocked") + ": " + block_date.reason,
"name": "_" + str(cnt),
})
cnt+=1

View File

@ -0,0 +1,10 @@
wn.views.calendar["Leave Application"] = wn.views.Calendar.extend({
field_map: {
"start": "from_date",
"end": "to_date",
"id": "name",
"title": "title",
"status": "status",
},
get_events_method: "hr.doctype.leave_application.leave_application.get_events"
})

View File

@ -30,7 +30,7 @@ class TestLeaveApplication(unittest.TestCase):
def test_global_block_list(self):
application = self.get_application(test_records[3])
application.doc.leave_approver = "test@example.com"
webnotes.conn.set_value("Holiday Block List", "_Test Holiday Block List",
webnotes.conn.set_value("Leave Block List", "_Test Leave Block List",
"applies_to_all_departments", 1)
webnotes.conn.set_value("Employee", "_T-Employee-0002", "department",
"_Test Department")
@ -47,6 +47,7 @@ class TestLeaveApplication(unittest.TestCase):
self.assertRaises(LeaveDayBlockedError, application.submit)
test_records = [
[{
"doctype": "Leave Allocation",

View File

@ -0,0 +1,66 @@
# For license information, please see license.txt
from __future__ import unicode_literals
import webnotes
from accounts.utils import validate_fiscal_year
from webnotes import _
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
def validate(self):
dates = []
for d in self.doclist.get({"doctype":"Leave Block List Date"}):
# validate fiscal year
validate_fiscal_year(d.block_date, self.doc.year, _("Block Date"))
# date is not repeated
if d.block_date in dates:
webnotes.msgprint(_("Date is repeated") + ":" + d.block_date, raise_exception=1)
dates.append(d.block_date)
@webnotes.whitelist()
def get_applicable_block_dates(from_date, to_date, employee=None,
company=None, all_lists=False):
block_dates = []
for block_list in get_applicable_block_lists(employee, company, all_lists):
block_dates.extend(webnotes.conn.sql("""select block_date, reason
from `tabLeave Block List Date` where parent=%s
and block_date between %s and %s""", (block_list, from_date, to_date),
as_dict=1))
return block_dates
def get_applicable_block_lists(employee=None, company=None, all_lists=False):
block_lists = []
if not employee:
employee = webnotes.conn.get_value("Employee", {"user_id":webnotes.session.user})
if not employee:
return []
if not company:
company = webnotes.conn.get_value("Employee", employee, "company")
def add_block_list(block_list):
if block_list:
if all_lists or not is_user_in_allow_list(block_list):
block_lists.append(block_list)
# per department
department = webnotes.conn.get_value("Employee",employee, "department")
if department:
block_list = webnotes.conn.get_value("Department", department, "leave_block_list")
add_block_list(block_list)
# global
for block_list in webnotes.conn.sql_list("""select name from `tabLeave Block List`
where ifnull(applies_to_all_departments,0)=1 and company=%s""", company):
add_block_list(block_list)
return list(set(block_lists))
def is_user_in_allow_list(block_list):
return webnotes.session.user in webnotes.conn.sql_list("""select allow_user
from `tabLeave Block List Allow` where parent=%s""", block_list)

View File

@ -1,13 +1,13 @@
[
{
"creation": "2013-02-04 15:31:29",
"creation": "2013-02-08 15:13:29",
"docstatus": 0,
"modified": "2013-02-08 11:36:20",
"modified": "2013-02-14 17:15:32",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "field:holiday_block_list_name",
"autoname": "field:leave_block_list_name",
"description": "Block Holidays on important days.",
"doctype": "DocType",
"document_type": "Master",
@ -17,7 +17,7 @@
{
"doctype": "DocField",
"name": "__common__",
"parent": "Holiday Block List",
"parent": "Leave Block List",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
@ -26,7 +26,7 @@
"create": 1,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Holiday Block List",
"parent": "Leave Block List",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
@ -36,13 +36,13 @@
},
{
"doctype": "DocType",
"name": "Holiday Block List"
"name": "Leave Block List"
},
{
"doctype": "DocField",
"fieldname": "holiday_block_list_name",
"fieldname": "leave_block_list_name",
"fieldtype": "Data",
"label": "Holiday Block List Name",
"label": "Leave Block List Name",
"reqd": 1
},
{
@ -77,10 +77,10 @@
},
{
"doctype": "DocField",
"fieldname": "holiday_block_list_dates",
"fieldname": "leave_block_list_dates",
"fieldtype": "Table",
"label": "Holiday Block List Dates",
"options": "Holiday Block List Date"
"label": "Leave Block List Dates",
"options": "Leave Block List Date"
},
{
"description": "Allow the following users to make Leave Applications for block days.",
@ -91,10 +91,10 @@
},
{
"doctype": "DocField",
"fieldname": "holiday_block_list_allowed",
"fieldname": "leave_block_list_allowed",
"fieldtype": "Table",
"label": "Holiday Block List Allowed",
"options": "Holiday Block List Allow"
"label": "Leave Block List Allowed",
"options": "Leave Block List Allow"
},
{
"doctype": "DocPerm"

View File

@ -0,0 +1,48 @@
import webnotes
import unittest
from hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
class TestLeaveBlockList(unittest.TestCase):
def test_get_applicable_block_dates(self):
webnotes.session.user = "test@example.com"
webnotes.conn.set_value("Department", "_Test Department", "leave_block_list",
"_Test Leave Block List")
self.assertTrue("2013-01-02" in
[d.block_date for d in get_applicable_block_dates("2013-01-01", "2013-01-03")])
def test_get_applicable_block_dates_for_allowed_user(self):
webnotes.session.user = "test1@example.com"
webnotes.conn.set_value("Department", "_Test Department 1", "leave_block_list",
"_Test Leave Block List")
self.assertEquals([], [d.block_date for d in get_applicable_block_dates("2013-01-01", "2013-01-03")])
def test_get_applicable_block_dates_all_lists(self):
webnotes.session.user = "test1@example.com"
webnotes.conn.set_value("Department", "_Test Department 1", "leave_block_list",
"_Test Leave Block List")
self.assertTrue("2013-01-02" in
[d.block_date for d in get_applicable_block_dates("2013-01-01", "2013-01-03", all_lists=True)])
test_dependencies = ["Employee"]
test_records = [[{
"doctype":"Leave Block List",
"leave_block_list_name": "_Test Leave Block List",
"year": "_Test Fiscal Year 2013",
"company": "_Test Company"
}, {
"doctype": "Leave Block List Date",
"parent": "_Test Leave Block List",
"parenttype": "Leave Block List",
"parentfield": "leave_block_list_dates",
"block_date": "2013-01-02",
"reason": "First work day"
}, {
"doctype": "Leave Block List Allow",
"parent": "_Test Leave Block List",
"parenttype": "Leave Block List",
"parentfield": "leave_block_list_allowed",
"allow_user": "test1@example.com",
}
]]

View File

@ -1,8 +1,8 @@
[
{
"creation": "2013-02-06 14:31:03",
"creation": "2013-02-14 17:37:38",
"docstatus": 0,
"modified": "2013-02-06 14:31:03",
"modified": "2013-02-14 17:41:53",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -19,15 +19,16 @@
"label": "Allow User",
"name": "__common__",
"options": "Profile",
"parent": "Holiday Block List Allow",
"parent": "Leave Block List Allow",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"reqd": 1,
"width": "200px"
},
{
"doctype": "DocType",
"name": "Holiday Block List Allow"
"name": "Leave Block List Allow"
},
{
"doctype": "DocField"

View File

@ -1,8 +1,8 @@
[
{
"creation": "2013-02-04 15:33:14",
"creation": "2013-02-14 17:37:38",
"docstatus": 0,
"modified": "2013-02-04 15:36:10",
"modified": "2013-02-14 17:41:44",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -15,15 +15,16 @@
{
"doctype": "DocField",
"name": "__common__",
"parent": "Holiday Block List Date",
"parent": "Leave Block List Date",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"reqd": 1,
"width": "200px"
},
{
"doctype": "DocType",
"name": "Holiday Block List Date"
"name": "Leave Block List Date"
},
{
"doctype": "DocField",

View File

@ -81,9 +81,9 @@ wn.module_page["HR"] = [
doctype: "Holiday List"
},
{
"label":wn._("Holiday Block List"),
"label":wn._("Leave Block List"),
"description":wn._("Block leave applications by department."),
doctype: "Holiday Block List"
doctype: "Leave Block List"
},
]
},

View File

@ -19,6 +19,6 @@ def execute():
webnotes.conn.set_value("Blog", page[0], "content", m)
# delete website cache
webnotes.conn.commit()
webnotes.delete_doc("DocType", "Web Cache")
webnotes.conn.commit()
webnotes.conn.sql("""drop table if exists `tabWeb Cache`""")

View File

@ -0,0 +1,14 @@
import webnotes
def execute():
webnotes.reload_doc("core", "doctype", "event")
webnotes.conn.sql("""update tabEvent set subject=description""")
webnotes.conn.sql("""update tabEvent set description = concat(description, "\n", notes)
where ifnull(notes,"") != "" """)
webnotes.conn.sql("""update tabEvent set starts_on = timestamp(event_date, event_hour)""")
webnotes.conn.sql("""update tabEvent set ends_on = timestampadd(hour, 1, starts_on)""")

View File

@ -169,5 +169,7 @@ patch_list = [
"patches.february_2013.update_company_in_leave_application",
"execute:webnotes.conn.sql_ddl('alter table tabSeries change `name` `name` varchar(100)')",
"execute:webnotes.conn.sql('update tabUserRole set parentfield=\"user_roles\" where parentfield=\"userroles\"')",
"patches.february_2013.fix_outstanding"
"patches.february_2013.fix_outstanding",
"patches.february_2013.p01_event",
"execute:webnotes.delete_doc('Page', 'Calendar')"
]

View File

@ -82,7 +82,7 @@ $.extend(wn.modules, {
icon: "icon-check"
},
"Calendar": {
link: "calendar",
link: "Calendar/Event",
color: "#026584",
label: wn._("Calendar"),
icon: "icon-calendar"

View File

@ -57,7 +57,7 @@ erpnext.toolbar.add_modules = function() {
</ul>\
</li>').prependTo('.navbar .nav:first');
var modules_list = wn.user.get_desktop_items();
var modules_list = wn.user.get_desktop_items().sort();
// add to dropdown
for(var i in modules_list) {

View File

@ -55,8 +55,6 @@ def boot_session(bootinfo):
bootinfo['letter_heads'] = get_letter_heads()
import webnotes.model.doctype
bootinfo['docs'] += webnotes.model.doctype.get('Event')
bootinfo['docs'] += webnotes.model.doctype.get('Search Criteria')
bootinfo['notification_settings'] = webnotes.doc("Notification Control",
"Notification Control").get_values()

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,165 +0,0 @@
/**** CALENDAR ****/
.cal_event {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin-bottom: 3px;
}
div.cal_body {
margin: 16px;
background-color: #DDD;
position: relative;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
padding: 16px;
-moz-box-shadow: 1px 1px 8px #555;
-webkit-box-shadow: 1px 1px 8px #555;
box-shadow: 1px 1px 8px #555;
}
div.cal_body h4 {
text-align: center;
}
div.cal_head {
margin: 16px;
margin-bottom: 0px;
}
div.cal_head div {
font-size: 18px;
color: #666;
padding-top: 8px;
}
div.cal_toolbar {
width: 80%;
}
div.cal_toolbar .btn {
text-align: center;
margin: 0px;
margin-left: -1px;
}
div.cal_view_body {
}
div.cal_view_body_plain {
margin: 16px;
}
div.cal_month_head {
margin: 8px 0px 8px 0px;
height: 30px;
}
div.cal_month_head .btn {
float: right;
}
span.cal_view_title {
display: inline-block;
font-size: 20px;
}
div.cal_month_body {
}
.cal_month_headtable {
table-layout:fixed;
width: 100%;
}
.cal_month_name {
width: 100%;
color: #888;
font-size: 14px;
font-weight: bold;
text-align: center;
}
.cal_month_headtable tr td{
font-size: 12px;
font-weight: bold;
text-align: center;
padding: 4px;
}
table.cal_month_table {
border-collapse: collapse;
table-layout:fixed;
width: 100%;
}
table.cal_month_table td {
width: 14.29%;
height: 20%;
/*overflow:hidden;*/
padding:0px;
}
div.cal_month_date {
width:100%;
font-size: 10px;
/*background-color: #EEF;*/
}
div.cal_month_date_holiday {
/*background-color: #FFF;*/
}
div.cal_month_unit {
width:100%;
min-height: 100px;
overflow:hidden;
cursor:pointer;
/*background-color:#FFF;*/
}
div.cal_vu_disabled {
background-color:#FFF;
cursor:default;
}
table.cal_day_table {
border-collapse: collapse;
width: 100%;
}
table.cal_day_table td {
}
div.cal_day_body {
width: 100%;
overflow-x: hidden;
border-top: 1px solid #AAA;
}
div.cal_day_unit{
width:100%;
cursor:pointer;
}
table.cal_week_table {
border-collapse: collapse;
table-layout: fixed;
width: 100%;
}
table.cal_week_table td {
width: 12.5%;
}
div.cal_week_body {
width: 100%;
overflow-x: hidden;
border-top: 1px solid #888;
}
div.cal_week_unit{
width: 100%;
cursor:pointer;
}

View File

@ -1,29 +0,0 @@
<div class="cal_body">
<a class="close" onclick="window.history.back();">&times;</a>
<div class="cal_toolbar btn-group">
<button class="btn btn-small" onclick="erpnext.calendar.add_event()">
<i class="icon-plus"></i> Add Event
</button>
<button class="btn btn-small" onclick="erpnext.calendar.refresh('Day')">
Day View
</button>
<button class="btn btn-small" onclick="erpnext.calendar.refresh('Week')">
Week View
</button>
<button class="btn btn-small" onclick="erpnext.calendar.refresh('Month')">
Month View
</button>
<button class="btn btn-small" onclick="erpnext.calendar.refresh(null, true)">
<i class="icon-refresh"></i> Refresh
</button>
</div>
<div class="cal_month_head">
<span class="cal_view_title"></span>
<button class="btn btn-small" onclick="erpnext.calendar.cur_view.next()">
<i class="icon-arrow-right"></i>
</button>
<button class="btn btn-small" onclick="erpnext.calendar.cur_view.prev()">
<i class="icon-arrow-left"></i>
</button>
</div>
</div>

View File

@ -1,710 +0,0 @@
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
//
// MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
pscript.onload_calendar = function(wrapper) {
if(!erpnext.calendar) {
erpnext.calendar = new Calendar();
erpnext.calendar.init(wrapper);
var me = this;
$(document).bind('rename', function(event, dt, old_name, new_name) {
erpnext.calendar.rename_notify(dt, old_name, new_name)
});
}
}
///// CALENDAR
Calendar=function() {
this.views=[];
this.events = {};
this.events_by_name = {};
this.weekdays = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
}
Calendar.prototype.init=function (parent) {
this.wrapper = parent;
this.body = $('.cal_body').get(0);
//this.make_head_buttons();
//this.make_header();
this.view_title = $('.cal_view_title').get(0);
this.todays_date = new Date();
this.selected_date = this.todays_date;
this.selected_hour = 8;
// Create views
this.views['Month'] = new Calendar.MonthView(this);
this.views['Week'] = new Calendar.WeekView(this);
this.views['Day'] = new Calendar.DayView(this);
// Month view as initial
this.cur_view = this.views['Month'];
this.views['Month'].show();
}
Calendar.prototype.rename_notify = function(dt, old_name, new_name) {
// calendar
if(dt = 'Event'){
if(this.events_by_name[old_name]) {
delete this.events_by_name[old_name];
}
}
}
//------------------------------------------------------
Calendar.prototype.show_event = function(ev, cal_ev) {
var me = this;
if(!this.event_dialog) {
var d = new Dialog(400, 400, 'Calendar Event');
d.make_body([
['HTML','Heading']
,['Text','Description']
,['HTML', 'Ref Link']
,['Check', 'Public Event']
,['Check', 'Cancelled Event']
,['HTML', 'Event Link']
,['Button', 'Save']
])
// show the event when the dialog opens
d.onshow = function() {
// heading
var c = me.selected_date;
this.widgets['Heading'].innerHTML =
'<div style="text-align: center; padding:4px; font-size: 14px">'
+ erpnext.calendar.weekdays[c.getDay()] + ', ' + c.getDate() + ' ' + month_list_full[c.getMonth()] + ' ' + c.getFullYear()
+ ' - <b>'+this.ev.event_hour+'</b></div>';
// set
this.widgets['Description'].value = cstr(this.ev.description);
this.widgets['Public Event'].checked = false;
this.widgets['Cancelled Event'].checked = false;
if(this.ev.event_type=='Public')
this.widgets['Public Event'].checked = true;
this.widgets['Event Link'].innerHTML = '';
this.widgets['Ref Link'].innerHTML = '';
if(this.ev.ref_type) {
$(repl('<table style="width: 100%;"><tr>\
<td style="width: 30%"><b>Reference:</b></td>\
<td><a href="#Form/%(ref_type)s/%(ref_name)s" \
onclick="cur_dialog.hide()">%(ref_type)s: %(ref_name)s</a></td>\
</tr></table>', this.ev))
.appendTo(this.widgets['Ref Link'])
}
$(repl('<a href="#Form/Event/%(name)s" \
onclick="cur_dialog.hide()">More Options</a>', this.ev))
.appendTo(this.widgets['Event Link'])
}
// event save
d.widgets['Save'].onclick = function() {
var d = me.event_dialog;
// save values
d.ev.description = d.widgets['Description'].value;
if(d.widgets['Cancelled Event'].checked)
d.ev.event_type='Cancel';
else if(d.widgets['Public Event'].checked)
d.ev.event_type='Public';
me.event_dialog.hide();
// if new event
me.save_event(d.ev);
}
this.event_dialog = d;
}
this.event_dialog.ev = ev;
this.event_dialog.cal_ev = cal_ev ? cal_ev : null;
this.event_dialog.show();
}
Calendar.prototype.save_event = function(doc) {
var me = this;
var doclist = new wn.model.DocList("Event", doc.name);
doclist.save("Save", function(r) {
var doc = locals['Event'][r.docname];
var cal = erpnext.calendar;
cal.cur_view.refresh();
// if cancelled, hide
if(doc.event_type=='Cancel') {
$(cal.events_by_name[doc.name].body).toggle(false);
}
})
}
//------------------------------------------------------
Calendar.prototype.add_event = function() {
var ev = wn.model.make_new_doc_and_get_name('Event');
ev = locals['Event'][ev];
ev.event_date = dateutil.obj_to_str(this.selected_date);
ev.event_hour = this.selected_hour+':00:00';
ev.event_type = 'Private';
this.show_event(ev);
}
//------------------------------------------------------
Calendar.prototype.get_month_events = function(call_back) {
// ret fn
var me = this;
var f = function(r, rt) {
if(me.cur_view) me.cur_view.refresh();
if(call_back)call_back();
}
//load
var y=this.selected_date.getFullYear(); var m = this.selected_date.getMonth();
if(!this.events[y] || !this.events[y][m]) {
$c('webnotes.widgets.event.load_month_events', args = {
'month': m + 1,
'year' : y},
f);
}
}
//------------------------------------------------------
Calendar.prototype.get_daily_event_list=function(day) {
var el = [];
var d = day.getDate(); var m = day.getMonth(); var y = day.getFullYear()
if(this.events[y] && this.events[y][m] &&
this.events[y][m][d]) {
var l = this.events[y][m][d]
for(var i in l) {
for(var j in l[i]) el[el.length] = l[i][j];
}
return el;
}
else return [];
}
//------------------------------------------------------
Calendar.prototype.set_event = function(ev) {
// don't duplicate
if(this.events_by_name[ev.name]) {
return this.events_by_name[ev.name];
}
var dt = dateutil.str_to_obj(ev.event_date);
var m = dt.getMonth();
var d = dt.getDate();
var y = dt.getFullYear();
if(!this.events[y]) this.events[y] = [];
if(!this.events[y][m]) this.events[y][m] = [];
if(!this.events[y][m][d]) this.events[y][m][d] = [];
if(!this.events[y][m][d][cint(ev.event_hour)])
this.events[y][m][d][cint(ev.event_hour)] = [];
var cal_ev = new Calendar.CalEvent(ev, this);
this.events[y][m][d][cint(ev.event_hour)].push(cal_ev);
this.events_by_name[ev.name] = cal_ev;
return cal_ev;
}
//------------------------------------------------------
Calendar.prototype.clear = function() {
this.events = {};
this.events_by_name = {};
locals.Event = {};
}
Calendar.prototype.refresh = function(viewtype, clear_events){//Sets the viewtype of the Calendar and Calls the View class based on the viewtype
if(viewtype)
this.viewtype = viewtype;
if(clear_events)
this.clear();
// switch view if reqd
if(this.cur_view.viewtype!=this.viewtype) {
this.cur_view.hide();
this.cur_view = this.views[this.viewtype];
this.cur_view.in_home = false; // for home page
this.cur_view.show();
}
else{
this.cur_view.get_events();
this.cur_view.refresh(this);
}
}
//------------------------------------------------------
Calendar.CalEvent= function(doc, cal) {
var me = this;
me.doc = doc;
this.body = $("<div class='label cal_event'></div>")
.html(doc.description)
.attr("title", doc.description)
.css({"cursor":"pointer"})
.attr("data-event", doc.name)
.click(function() {
var doc = locals["Event"][$(this).attr("data-event")];
cal.show_event(doc, me);
})
this.show = function(vu) {
me.body
.html(me.doc.description)
.css({"width": ($(vu.body).width()-10)})
.appendTo(vu.body)
.removeClass("label-success").removeClass("label-info")
.addClass(me.doc.event_type=="Public" ? "label-success" : "label-info")
}
}
// ----------
Calendar.View =function() { this.daystep = 0; this.monthstep = 0; }
Calendar.View.prototype.init=function(cal) {
this.cal = cal;
this.body = $a(cal.body, 'div', 'cal_view_body');
this.body.style.display = 'none';
this.create_table();
}
Calendar.View.prototype.show=function() {
this.body.style.display = 'block';
this.get_events(); this.refresh();
}
Calendar.View.prototype.hide=function() {
this.body.style.display = 'none';
}
Calendar.View.prototype.next = function() {
var s = this.cal.selected_date;
this.cal.selected_date = new Date(s.getFullYear(), s.getMonth() + this.monthstep, s.getDate() + this.daystep);
this.get_events(); this.refresh();
}
Calendar.View.prototype.prev = function() {
var s = this.cal.selected_date;
this.cal.selected_date = new Date(s.getFullYear(), s.getMonth() - this.monthstep, s.getDate() - this.daystep);
this.get_events(); this.refresh();
}
Calendar.View.prototype.get_events = function() {
this.cal.get_month_events();
}
Calendar.View.prototype.add_unit = function(vu) {
this.viewunits[this.viewunits.length] = vu;
}
Calendar.View.prototype.refresh_units = function() {
// load the events
if(locals['Event']) {
for(var name in locals['Event']) {
this.cal.set_event(locals['Event'][name]);
}
}
for(var r in this.table.rows) {
for(var c in this.table.rows[r].cells) {
if(this.table.rows[r].cells[c].viewunit) {
this.table.rows[r].cells[c].viewunit.refresh();
}
}
}
}
// ................. Month View..........................
Calendar.MonthView = function(cal) { this.init(cal); this.monthstep = 1; this.rows = 5; this.cells = 7; }
Calendar.MonthView.prototype=new Calendar.View();
Calendar.MonthView.prototype.create_table = function() {
// create head
this.head_wrapper = $a(this.body, 'div', 'cal_month_head');
// create headers
this.headtable = $a(this.head_wrapper, 'table', 'cal_month_headtable');
var r = this.headtable.insertRow(0);
for(var j=0;j<7;j++) {
var cell = r.insertCell(j);
cell.innerHTML = erpnext.calendar.weekdays[j];
$w(cell, (100 / 7) + '%');
}
this.main = $a(this.body, 'div', 'cal_month_body');
this.table = $a(this.main, 'table', 'cal_month_table');
var me = this;
// create body
for(var i=0;i<5;i++) {
var r = this.table.insertRow(i);
for(var j=0;j<7;j++) {
var cell = r.insertCell(j);
cell.viewunit = new Calendar.MonthViewUnit(cell);
}
}
}
Calendar.MonthView.prototype.refresh = function() {
var c =this.cal.selected_date;
var me=this;
// fill other days
var cur_row = 0;
var cur_month = c.getMonth();
var cur_year = c.getFullYear();
var d = new Date(cur_year, cur_month, 1);
var day = 1 - d.getDay();
// set day headers
var d = new Date(cur_year, cur_month, day);
this.cal.view_title.innerHTML = month_list_full[cur_month] + ' ' + cur_year;
for(var i=0;i<6;i++) {
if((i<5) || cur_month==d.getMonth()) { // if this month
for(var j=0;j<7;j++) {
var cell = this.table.rows[cur_row].cells[j];
if((i<5) || cur_month==d.getMonth()) { // if this month
cell.viewunit.day = d;
cell.viewunit.hour = 8;
if(cur_month == d.getMonth()) {
cell.viewunit.is_disabled = false;
if(same_day(this.cal.todays_date, d))
cell.viewunit.is_today = true;
else
cell.viewunit.is_today = false;
} else {
cell.viewunit.is_disabled = true;
}
}
// new date
day++;
d = new Date(cur_year, cur_month, day);
}
}
cur_row++;
if(cur_row == 5) {cur_row = 0;} // back to top
}
this.refresh_units();
}
// ................. Daily View..........................
Calendar.DayView=function(cal){ this.init(cal); this.daystep = 1; }
Calendar.DayView.prototype=new Calendar.View();
Calendar.DayView.prototype.create_table = function() {
// create body
this.main = $a(this.body, 'div', 'cal_day_body');
this.table = $a(this.main, 'table', 'cal_day_table');
var me = this;
for(var i=0;i<24;i++) {
var r = this.table.insertRow(i);
for(var j=0;j<2;j++) {
var cell = r.insertCell(j);
if(j==0) {
cell.innerHTML = i+':00:00';
$w(cell, '10%');
} else {
cell.viewunit = new Calendar.DayViewUnit(cell);
cell.viewunit.hour = i;
$w(cell, '90%');
if((i>=7)&&(i<=20)) {
cell.viewunit.is_daytime = true;
}
}
}
}
}
Calendar.DayView.prototype.refresh = function() {
var c =this.cal.selected_date;
// fill other days
var me=this;
this.cal.view_title.innerHTML = erpnext.calendar.weekdays[c.getDay()] + ', '
+ c.getDate() + ' ' + month_list_full[c.getMonth()] + ' ' + c.getFullYear();
// headers
var d = c;
for(var i=0;i<24;i++) {
var cell = this.table.rows[i].cells[1];
if(same_day(this.cal.todays_date, d)) cell.viewunit.is_today = true;
else cell.viewunit.is_today = false;
cell.viewunit.day = d;
}
this.refresh_units();
}
// ................. Weekly View..........................
Calendar.WeekView=function(cal) { this.init(cal); this.daystep = 7; }
Calendar.WeekView.prototype=new Calendar.View();
Calendar.WeekView.prototype.create_table = function() {
// create head
this.head_wrapper = $a(this.body, 'div', 'cal_month_head');
// day headers
this.headtable = $a(this.head_wrapper, 'table', 'cal_month_headtable');
var r = this.headtable.insertRow(0);
for(var j=0;j<8;j++) {
var cell = r.insertCell(j);
}
// hour header
// create body
this.main = $a(this.body, 'div', 'cal_week_body');
this.table = $a(this.main, 'table', 'cal_week_table');
var me = this;
for(var i=0;i<24;i++) {
var r = this.table.insertRow(i);
for(var j=0;j<8;j++) {
var cell = r.insertCell(j);
if(j==0) {
cell.innerHTML = i+':00:00';
$w(cell, '10%');
} else {
cell.viewunit = new Calendar.WeekViewUnit(cell);
cell.viewunit.hour = i;
if((i>=7)&&(i<=20)) {
cell.viewunit.is_daytime = true;
}
}
}
}
}
Calendar.WeekView.prototype.refresh = function() {
var c =this.cal.selected_date;
// fill other days
var me=this;
this.cal.view_title.innerHTML = month_list_full[c.getMonth()] + ' ' + c.getFullYear();
// headers
var d = new Date(c.getFullYear(), c.getMonth(), c.getDate() - c.getDay());
for (var k=1;k<8;k++) {
this.headtable.rows[0].cells[k].innerHTML = erpnext.calendar.weekdays[d.getDay()] + ' ' + d.getDate();
for(var i=0;i<24;i++) {
var cell = this.table.rows[i].cells[k];
if(same_day(this.cal.todays_date, d))
cell.viewunit.is_today = true;
else cell.viewunit.is_today = false;
cell.viewunit.day = d;
//cell.viewunit.refresh();
}
d=new Date(d.getFullYear(),d.getMonth(),d.getDate() + 1);
}
this.refresh_units();
}
//------------------------------------------------------.
Calendar.ViewUnit = function() {}
Calendar.ViewUnit.prototype.init = function(parent) {
parent.style.border = "1px solid #CCC" ;
this.body = $a(parent, 'div', this.default_class);
this.parent = parent;
var me = this;
this.body.onclick = function() {
erpnext.calendar.selected_date = me.day;
erpnext.calendar.selected_hour = me.hour;
if(erpnext.calendar.cur_vu && erpnext.calendar.cur_vu!=me){
erpnext.calendar.cur_vu.deselect();
me.select();
erpnext.calendar.cur_vu = me;
}
}
this.body.ondblclick = function() {
erpnext.calendar.add_event();
}
}
Calendar.ViewUnit.prototype.set_header=function(v) {
this.header.innerHTML = v;
}
Calendar.ViewUnit.prototype.set_today = function() {
this.is_today = true;
this.set_display();
}
Calendar.ViewUnit.prototype.clear = function() {
if(this.header)this.header.innerHTML = '';
// clear body
while(this.body.childNodes.length)
this.body.removeChild(this.body.childNodes[0]);
}
Calendar.ViewUnit.prototype.set_display = function() {
var cn = '#FFF';
// colors
var col_tod_sel = '#EEE';
var col_tod = '#FFF';
var col_sel = '#EEF';
if(this.is_today) {
if(this.selected) cn = col_tod_sel;
else cn = col_tod;
} else
if(this.selected) cn = col_sel;
if(this.header) {
if(this.is_disabled) {
this.body.className = this.default_class + ' cal_vu_disabled';
this.header.style.color = '#BBB';
} else {
this.body.className = this.default_class;
this.header.style.color = '#000';
}
if(this.day&&this.day.getDay()==0)
this.header.style.backgroundColor = '#FEE';
else
this.header.style.backgroundColor = '';
}
this.parent.style.backgroundColor = cn;
}
Calendar.ViewUnit.prototype.is_selected = function() {
return (same_day(this.day, erpnext.calendar.selected_date)
&& this.hour==erpnext.calendar.selected_hour)
}
Calendar.ViewUnit.prototype.get_event_list = function() {
var y = this.day.getFullYear();
var m = this.day.getMonth();
var d = this.day.getDate();
if(erpnext.calendar.events[y] && erpnext.calendar.events[y][m] &&
erpnext.calendar.events[y][m][d] &&
erpnext.calendar.events[y][m][d][this.hour]) {
return erpnext.calendar.events[y][m][d][this.hour];
} else
return [];
}
Calendar.ViewUnit.prototype.refresh = function() {
this.clear();
if(this.is_selected()) {
if(erpnext.calendar.cur_vu)erpnext.calendar.cur_vu.deselect();
this.selected = true;
erpnext.calendar.cur_vu = this;
}
this.set_display();
this.el = this.get_event_list();
if(this.onrefresh)this.onrefresh();
for(var i in this.el) {
this.el[i].show(this);
}
var me = this;
}
Calendar.ViewUnit.prototype.select=function() { this.selected = true; this.set_display(); }
Calendar.ViewUnit.prototype.deselect=function() { this.selected = false; this.set_display(); }
Calendar.ViewUnit.prototype.setevent=function() { }
Calendar.MonthViewUnit=function(parent) {
var me = this;
this.header = $("<div class='cal_month_date'></div>")
.appendTo(parent)
.css({"cursor":"pointer"})
.click(function() {
me.body.onclick();
})
.bind("dblclick", function() {
me.body.ondblclick();
})
.get(0);
this.default_class = "cal_month_unit";
this.init(parent);
this.onrefresh = function() {
this.header.innerHTML = this.day.getDate();
}
}
Calendar.MonthViewUnit.prototype = new Calendar.ViewUnit();
Calendar.MonthViewUnit.prototype.is_selected = function() {
return same_day(this.day, erpnext.calendar.selected_date)
}
Calendar.MonthViewUnit.prototype.get_event_list = function() {
return erpnext.calendar.get_daily_event_list(this.day);
}
Calendar.DayViewUnit= function(parent) {
this.default_class = "cal_day_unit"; this.init(parent);
}
Calendar.DayViewUnit.prototype = new Calendar.ViewUnit();
Calendar.DayViewUnit.prototype.onrefresh = function() {
if(this.el.length<3)
this.body.style.height = '30px';
else this.body.style.height = '';
}
Calendar.WeekViewUnit=function(parent) {
this.default_class = "cal_week_unit"; this.init(parent);
}
Calendar.WeekViewUnit.prototype = new Calendar.ViewUnit();
Calendar.WeekViewUnit.prototype.onrefresh = function() {
if(this.el.length<3) this.body.style.height = '30px';
else this.body.style.height = '';
}

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,21 +0,0 @@
[
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-02-24 11:24:12",
"modified_by": "Administrator",
"modified": "2012-02-24 11:24:12"
},
{
"name": "__common__",
"title": "Calendar",
"module": "Utilities",
"doctype": "Page",
"page_name": "calendar",
"standard": "Yes"
},
{
"name": "calendar",
"doctype": "Page"
}
]

View File

@ -66,12 +66,14 @@ def get_active_users(arg=None):
def post(arg=None):
import webnotes
"""post message"""
if arg:
import json
arg = json.loads(arg)
else:
if not arg:
arg = {}
arg.update(webnotes.form_dict)
if isinstance(arg, basestring):
import json
arg = json.loads(arg)
from webnotes.model.doc import Document
d = Document('Comment')
d.parenttype = arg.get("parenttype")
@ -90,16 +92,13 @@ def delete(arg=None):
webnotes.form_dict['name']);
def notify(arg=None):
from webnotes.utils import cstr
from webnotes.utils import cstr, get_fullname
from startup import get_url
fn = webnotes.conn.sql('select first_name, last_name from tabProfile where name=%s', webnotes.user.name)[0]
if fn[0] or f[1]:
fn = cstr(fn[0]) + (fn[0] and ' ' or '') + cstr(fn[1])
else:
fn = webnotes.user.name
fn = get_fullname(webnotes.user.name) or webnotes.user.name
url = get_url()
message = '''You have a message from <b>%s</b>:
%s
@ -108,8 +107,11 @@ def notify(arg=None):
<a href=\"%s\" target='_blank'>%s</a>
''' % (fn, arg['txt'], url, url)
sender = webnotes.user.name!='Administrator' and webnotes.user.name or 'support+admin_post@erpnext.com'
sender = webnotes.conn.get_value("Profile", webnotes.user.name, "email") \
or webnotes.user.name
recipient = [webnotes.conn.get_value("Profile", arg["contact"], "email") \
or arg["contact"]]
from webnotes.utils.email_lib import sendmail
sendmail([arg['contact']], sender, message, "You have a message from %s" % (fn,))
sendmail(recipient, sender, message, arg.get("subject") or "You have a message from %s" % (fn,))