Merge pull request #15376 from jodeq/show_project-attachments-in-portal

[Proposal] Show project attachments in portal view
diff --git a/erpnext/projects/doctype/project_user/project_user.json b/erpnext/projects/doctype/project_user/project_user.json
index a7cc810..5966816 100644
--- a/erpnext/projects/doctype/project_user/project_user.json
+++ b/erpnext/projects/doctype/project_user/project_user.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
  "beta": 0, 
@@ -11,16 +12,21 @@
  "editable_grid": 1, 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "user", 
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "User", 
    "length": 0, 
    "no_copy": 0, 
@@ -30,23 +36,30 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
    "search_index": 1, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "welcome_email_sent", 
    "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Welcome email sent", 
    "length": 0, 
    "no_copy": 0, 
@@ -55,24 +68,58 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 1, 
+   "fieldname": "view_attachments", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "View attachments", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "idx": 0, 
  "image_view": 0, 
  "in_create": 0, 
-
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-11 03:28:04.756894", 
+ "modified": "2018-09-09 12:39:38.376816", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Project User", 
@@ -82,7 +129,10 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
- "track_seen": 0
+ "track_changes": 0, 
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/templates/includes/projects/project_timesheets.html b/erpnext/templates/includes/projects/project_timesheets.html
index 66f4771..fb3806c 100644
--- a/erpnext/templates/includes/projects/project_timesheets.html
+++ b/erpnext/templates/includes/projects/project_timesheets.html
@@ -2,16 +2,16 @@
 <div class='timesheet'>
 	<a class="no-decoration timesheet-link {{ timesheet.css_seen }}" href="/timesheet/{{ timesheet.info.name}}">
 		<div class='row project-item'>
-			<div class='col-xs-9'>
+			<div class='col-xs-10'>
 				<span class="indicator {{ "blue" if timesheet.info.status=="Submitted" else "red" if timesheet.info.status=="Draft" else "darkgrey" }}" title="{{ timesheet.info.status }}"  > {{ timesheet.info.name }} </span> 
 				<div class="small text-muted item-timestamp">
 				{{ _("From") }} {{ frappe.format_date(timesheet.from_time) }} {{ _("to") }} {{ frappe.format_date(timesheet.to_time) }}
 			</div>
 			</div>
-				<div class='col-xs-1 gravatar-top'>
-				<span class="avatar avatar-small" title="{{ timesheet.info.modified_by }}"> <img src="{{ timesheet.info.user_image }}"></span>
+				<div class='col-xs-1' style="margin-right:-30px;">
+				<span class="avatar avatar-small" title="{{ timesheet.info.modified_by }}"> <img src="{{ timesheet.info.user_image }}" style="display:flex;"></span>
 			</div> 
-			<div class='col-xs-2'>
+			<div class='col-xs-1'>
 				<span class="pull-right list-comment-count small {{ "text-extra-muted" if timesheet.comment_count==0 else "text-muted" }}">
 				<i class="octicon octicon-comment-discussion"></i>
 				{{ timesheet.info.comment_count }}
diff --git a/erpnext/templates/pages/projects.html b/erpnext/templates/pages/projects.html
index 765e43f..baa2ae6 100644
--- a/erpnext/templates/pages/projects.html
+++ b/erpnext/templates/pages/projects.html
@@ -57,10 +57,34 @@
 {% else %}
 	<p class="text-muted">{{ _("No time sheets") }}</p>
 {% endif %}
+
+{% if doc.attachments %}
+<div class='padding'></div>
+
+<h4>{{ _("Attachments") }}</h4>
+	<div class="project-attachments">
+		{% for attachment in doc.attachments %}
+		<div class="attachment">
+			<a class="no-decoration attachment-link" href="{{ attachment.file_url }}" target="blank">
+				<div class="row">
+					<div class="col-xs-9">
+						<span class="indicator red file-name"> {{ attachment.file_name }}</span>
+					</div>
+					<div class="col-xs-3">
+						<span class="pull-right file-size">{{ attachment.file_size }}</span>
+					</div>
+				</div>
+			</a>
+		</div>
+		{% endfor %}
+	</div>
+{% endif %}
+
 </div>
 
 <script>
-	{% include "erpnext/templates/pages/projects.js" %}
+	{% include "frappe/public/js/frappe/provide.js" %}
+	{% include "frappe/public/js/frappe/form/formatters.js" %}
 </script>
 
 {% endblock %}
diff --git a/erpnext/templates/pages/projects.js b/erpnext/templates/pages/projects.js
index 99f0663..b6a2553 100644
--- a/erpnext/templates/pages/projects.js
+++ b/erpnext/templates/pages/projects.js
@@ -36,6 +36,10 @@
 		more_items('timeline', false);
 	});
 
+	$(".file-size").each(function() {
+		$(this).text(frappe.form.formatters.FileSize($(this).text()));
+	});
+
 
 	var reload_items = function(item_status, item, $btn) {
 		$.ajax({
diff --git a/erpnext/templates/pages/projects.py b/erpnext/templates/pages/projects.py
index d68770d..ddca274 100644
--- a/erpnext/templates/pages/projects.py
+++ b/erpnext/templates/pages/projects.py
@@ -6,7 +6,7 @@
 import json
 
 def get_context(context):
-	project_user = frappe.db.get_value("Project User", {"parent": frappe.form_dict.project, "user": frappe.session.user} , "user")
+	project_user = frappe.db.get_value("Project User", {"parent": frappe.form_dict.project, "user": frappe.session.user} , ["user", "view_attachments"], as_dict= True)
 	if not project_user or frappe.session.user == 'Guest': 
 		raise frappe.PermissionError
 		
@@ -22,6 +22,8 @@
 	project.timesheets = get_timesheets(project.name, start=0,
 		search=frappe.form_dict.get("search"))
 
+	if project_user.view_attachments:
+		project.attachments = get_attachments(project.name)
 
 	context.doc = project
 
@@ -92,3 +94,6 @@
 	return frappe.render_template("erpnext/templates/includes/projects/project_timesheets.html",
 		{"doc": {"timesheets": get_timesheets(project, start)}}, is_path=True)
 
+def get_attachments(project):
+	return frappe.get_all('File', filters= {"attached_to_name": project, "attached_to_doctype": 'Project', "is_private":0},
+		fields=['file_name','file_url', 'file_size'])