Website data from existing child tables, layout, images

This commit is contained in:
pratu16x7 2017-02-13 21:52:43 +05:30
parent dee36e10ae
commit 60fe77cc90
9 changed files with 280 additions and 49 deletions

View File

@ -1230,7 +1230,7 @@
"label": "Website",
"length": 0,
"no_copy": 0,
"options": "fa fa-globe",
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -1248,7 +1248,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.variant_of",
"depends_on": "",
"fieldname": "show_in_website",
"fieldtype": "Check",
"hidden": 0,
@ -1299,7 +1299,7 @@
"unique": 0
},
{
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@ -1328,7 +1328,7 @@
"unique": 0
},
{
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@ -1358,7 +1358,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "",
"collapsible_depends_on": "website_items",
"columns": 0,
"depends_on": "show_in_website",
"fieldname": "sb_web_spec",
@ -1384,7 +1384,7 @@
"unique": 0
},
{
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@ -1412,7 +1412,7 @@
"unique": 0
},
{
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@ -1440,7 +1440,7 @@
"unique": 0
},
{
"allow_on_submit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
@ -1469,11 +1469,11 @@
"unique": 0
},
{
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "show_in_website",
"depends_on": "eval:(doc.show_in_website && doc.with_operations)",
"fieldname": "show_operations",
"fieldtype": "Check",
"hidden": 0,
@ -1497,7 +1497,7 @@
"unique": 0
},
{
"allow_on_submit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
@ -1537,7 +1537,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-02-10 07:52:53.599831",
"modified": "2017-02-12 23:16:15.994194",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",

View File

@ -54,6 +54,8 @@ class BOM(WebsiteGenerator):
self.set_bom_material_details()
self.validate_operations()
self.calculate_cost()
self.validate_website_image()
self.make_thumbnail()
def get_context(self, context):
context.parents = [{'name': 'boms', 'title': _('All BOMs') }]
@ -452,6 +454,7 @@ class BOM(WebsiteGenerator):
'item_code' : d.item_code,
'item_name' : d.item_name,
'description' : d.description,
'qty' : d.qty,
'website_image' : d.image
}))
@ -495,6 +498,86 @@ class BOM(WebsiteGenerator):
ch.docstatus = self.docstatus
ch.db_insert()
def validate_website_image(self):
"""Validate if the website image is a public file"""
auto_set_website_image = False
if not self.website_image and self.image:
auto_set_website_image = True
self.website_image = self.image
if not self.website_image:
return
# find if website image url exists as public
file_doc = frappe.get_all("File", filters={
"file_url": self.website_image
}, fields=["name", "is_private"], order_by="is_private asc", limit_page_length=1)
if file_doc:
file_doc = file_doc[0]
if not file_doc:
if not auto_set_website_image:
frappe.msgprint(_("Website Image {0} attached to Item {1} cannot be found")
.format(self.website_image, self.name))
self.website_image = None
elif file_doc.is_private:
if not auto_set_website_image:
frappe.msgprint(_("Website Image should be a public file or website URL"))
self.website_image = None
def make_thumbnail(self):
"""Make a thumbnail of `website_image`"""
import requests.exceptions
if not self.is_new() and self.website_image != frappe.db.get_value(self.doctype, self.name, "website_image"):
self.thumbnail = None
if self.website_image and not self.thumbnail:
file_doc = None
try:
file_doc = frappe.get_doc("File", {
"file_url": self.website_image,
"attached_to_doctype": "Item",
"attached_to_name": self.name
})
except frappe.DoesNotExistError:
pass
# cleanup
frappe.local.message_log.pop()
except requests.exceptions.HTTPError:
frappe.msgprint(_("Warning: Invalid attachment {0}").format(self.website_image))
self.website_image = None
except requests.exceptions.SSLError:
frappe.msgprint(_("Warning: Invalid SSL certificate on attachment {0}").format(self.website_image))
self.website_image = None
# for CSV import
if self.website_image and not file_doc:
try:
file_doc = frappe.get_doc({
"doctype": "File",
"file_url": self.website_image,
"attached_to_doctype": "Item",
"attached_to_name": self.name
}).insert()
except IOError:
self.website_image = None
if file_doc:
if not file_doc.thumbnail_url:
file_doc.make_thumbnail()
self.thumbnail = file_doc.thumbnail_url
def get_list_context(context):
context.title = _("Bill of Materials")
# context.introduction = _('Boms')

View File

@ -159,7 +159,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-02-10 07:34:33.625474",
"modified": "2017-02-12 12:48:56.949861",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Website Item",

View File

@ -120,6 +120,33 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "thumbnail",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Thumbnail",
"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,
"unique": 0
}
],
"hide_heading": 0,
@ -132,7 +159,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-02-10 07:34:30.479443",
"modified": "2017-02-12 16:32:44.316447",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Website Operation",

View File

@ -250,3 +250,27 @@
.product-image-wrapper {
padding-bottom: 40px;
}
.duration-bar {
display: inline-block;
color: white;
/* border-right: 2px solid green; */
background: #8FD288;
padding: 3px;
}
.duration-invisible {
visibility: hidden;
}
.duration-value {
float: right;
}
.bar-outer-text {
color: #8FD288;
background: none;
float: none;
border: none;
}
.thumbsize {
width: 200px;
height: 200px;
padding: 0;
}

View File

@ -320,4 +320,33 @@
.product-image-wrapper {
padding-bottom: 40px;
}
.duration-bar {
display: inline-block;
color: white;
/* border-right: 2px solid green; */
background: #8FD288;
padding: 3px;
}
.duration-invisible {
visibility: hidden;
}
.duration-value {
float: right;
}
.bar-outer-text {
color: #8FD288;
background: none;
float: none;
border: none;
}
.thumbsize {
width: 200px;
height: 200px;
padding: 0;
}

View File

@ -8,48 +8,50 @@
{% block page_content %}
{% from "erpnext/templates/includes/macros.html" import product_image %}
<div class="item-content" style="margin-top:20px;">
<div class="product-page-content" itemscope itemtype="http://schema.org/Product">
{% from "erpnext/templates/includes/macros.html" import media_image %}
<div class="bom-content" style="margin-top:20px;">
<div class="bom-page-content" itemscope itemtype="http://schema.org/Product">
<div class="row">
<div class="col-sm-6">
{% if slideshow %}
{% include "templates/includes/slideshow.html" %}
{% else %}
{{ product_image(website_image, "product-full-image") }}
{% endif %}
</div>
<div class="col-sm-6" style="padding-left:20px;">
<h2 itemprop="name" style="margin-top: 0px;">{{ name }}</h2>
<div class="col-sm-12">
<h2 itemprop="name" style="margin-top: 0px;">{{ name }}</h2>
<p class="text-muted">
{{ _("Item Name") }}: <span itemprop="itemName">{{ item_name }}</span></p>
<br>
<!--{{ _("Item Code") }}: <span itemprop="productID">{{ item_code }}</span></p>-->
<div class="h6 text-uppercase">{{ _("Description") }}</div>
<div itemprop="description" class="item-desc">
{{ web_long_description or description or _("No description given") }}</div>
<br>
<div class="h6 text-uppercase">{{ _("Quantity") }}</div>
<div itemprop="quantity" class="item-desc">{{ quantity }}</div>
{{ _("Item") }}: <span itemprop="itemName">{{ item_name }}</span></p>
<br>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
{{ product_image(website_image, "product-full-image") }}
<br>
<p>{{ _("Quantity") }}: <span itemprop="productID">{{ quantity }}</span></p>
<br>
</div>
</div>
{% if show_items -%}
<div class="row items" style="margin-top: 40px">
<div class="col-md-12">
<div class="h6 text-uppercase">{{ _("Items") }}</div>
<h3>{{ _("Items") }}</h3>
<table class="table borderless" style="width: 100%">
{% for d in website_items -%}
<tr>
<td class="uppercase text-muted" style="width: 30%;">{{ d.item_name }}</td>
<td>{{ d.item_code }}</td>
<td>{{ d.description }}</td>
<th></th>
<th></th>
<th>{{ _("Qty") }}</th>
</tr>
{% for d in items -%}
<tr>
<td>{{ media_image(d.image, "product-full-image") }}</td>
<td><div><b>{{ d.item_name }}</b></div>
{% if d.item_name != d.item_code -%}
<div class="text-muted">{{ d.item_code }}</div>
{% else -%}
{%- endif %}
<br>
{{ d.description }}
</td>
<td>{{ d.qty }}</td>
</tr>
{%- endfor %}
@ -61,15 +63,25 @@
{% if show_operations -%}
<div class="row operations" style="margin-top: 40px">
<div class="col-md-12">
<div class="h6 text-uppercase">{{ _("Operations") }}</div>
<h3>{{ _("Operations") }}</h3>
<table class="table borderless" style="width: 100%">
{% for d in website_operations -%}
<tr>
<td class="uppercase text-muted" style="width: 30%;">{{ d.operation }}</td>
<th></th>
<th style="padding:8px 20px;"></th>
<th>{{ _("Workstation") }}</th>
<th style="width: 20%;">{{ _("Time(in mins)") }}</th>
</tr>
{% for d in operations -%}
<tr>
<td>{{ media_image(d.image, d.operation, "product-full-image") }}</td>
<td style="padding:8px 20px;"><div>{{ d.operation }}</div>
<div class="text-muted">{{ d.description }}</div>
</td>
<td>{{ d.workstation }}</td>
<td>{{ d.time_in_mins }}</td>
<td>{{ d.website_image }}</td>
<td class="duration" style="width: 20%;"><span class="duration-bar">
<span class="duration-value">{{ d.time_in_mins }}</span></span></td>
</tr>
{%- endfor %}
</table>
@ -77,6 +89,39 @@
</div>
{%- endif %}
<div class="row" style="margin-top: 30px;">
<div class="col-sm-12">
<br>
<div class="h6 text-uppercase">{{ _("Description") }}</div>
<div itemprop="description" class="item-desc">
{{ web_long_description or _("No description given") }}</div>
<br>
</div>
</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script>
var max_width = $(".duration").width() * 0.8;
var durations = [];
$(".duration .duration-bar").each(function() {
durations.push($(this).find(".duration-value").html());
});
var max_duration = Math.max(...durations);
var width_factor = max_width/max_duration;
$(".duration .duration-bar").each(function() {
var duration = $(this).find(".duration-value").html();
$(this).width(duration * width_factor);
if($(this).width() < $(this).find(".duration-value").width()) {
var html = $($(this).html());
html.addClass("duration-bar");
html.addClass("bar-outer-text");
$(this).find(".duration-value").removeClass("duration-value").addClass("duration-invisible");
$(this).closest("td").append(html);
}
});
</script>
{% endblock %}

View File

@ -19,3 +19,26 @@
{%- endif %}
</div>
{% endmacro %}
{% macro media_image(website_image, name, css_class="") %}
{% if website_image -%}
<meta itemprop="image" content="{{ frappe.utils.quoted(website_image) | abs_url }}"></meta>
{%- endif %}
<div class="product-image product-image-square thumbsize {{ css_class }}"
{% if not website_image -%}{{ name }}{%- endif %}
{% if website_image -%}
style="background-image: url('{{ frappe.utils.quoted(website_image) | abs_url }}');"
{%- endif %}>
</div>
{% endmacro %}
{% macro bom_image(website_image, name, css_class="") %}
<div class="product-image {{ css_class }}">
{% if not website_image -%}{{ name }}{%- endif %}
{% if website_image -%}
<a href="{{ frappe.utils.quoted(website_image) }}">
<img itemprop="image" src="{{ frappe.utils.quoted(website_image) | abs_url }}" class="img-responsive">
</a>
{%- endif %}
</div>
{% endmacro %}

View File

@ -18,7 +18,7 @@
<a class="product-link" href="{{ item.route|abs_url }}">
<div class="col-sm-4 col-xs-4 product-image-wrapper">
<div class="product-image-img">
{{ product_image_square(item.thumbnail or item.image) }}
{{ product_image_square(item.thumbnail or item.image) }}
<div class="product-text" itemprop="name">{{ item.item_name }}</div>
</div>
</div>