-num">
@@ -0,0 +1,191 @@
1
+;(function($, yl) {
2
+    yl.forwardHandlerRegistry = yl.forwardHandlerRegistry || {};
3
+
4
+    yl.registerForwardHandler = function(name, handler) {
5
+        yl.forwardHandlerRegistry[name] = handler;
6
+    };
7
+
8
+    yl.getForwardHandler = function(name) {
9
+        return yl.forwardHandlerRegistry[name];
10
+    };
11
+
12
+    function getForwardStrategy(element) {
13
+        var checkForCheckboxes = function() {
14
+            var all = true;
15
+            $.each(element, function(ix, e) {
16
+                if ($(e).attr("type") !== "checkbox") {
17
+                    all = false;
18
+                }
19
+            });
20
+            return all;
21
+        };
22
+
23
+        if (element.length === 1 &&
24
+                element.attr("type") === "checkbox" &&
25
+                element.attr("value") === undefined) {
26
+            // Single checkbox without 'value' attribute
27
+            // Boolean field
28
+            return "exists";
29
+        } else if (element.length === 1 &&
30
+                element.attr("multiple") !== undefined) {
31
+            // Multiple by HTML semantics. E. g. multiple select
32
+            // Multiple choice field
33
+            return "multiple";
34
+        } else if (checkForCheckboxes()) {
35
+            // Multiple checkboxes or one checkbox with 'value' attribute.
36
+            // Multiple choice field represented by checkboxes
37
+            return "multiple";
38
+        } else {
39
+            // Other cases
40
+            return "single";
41
+        }
42
+    }
43
+
44
+    /**
45
+     * Get fields with name `name` relative to `element` with considering form
46
+     * prefixes.
47
+     * @param element the element
48
+     * @param name name of the field
49
+     * @returns jQuery object with found fields or empty jQuery object if no
50
+     * field was found
51
+     */
52
+    yl.getFieldRelativeTo = function(element, name) {
53
+        var prefixes = $(element).getFormPrefixes();
54
+
55
+        for (var i = 0; i < prefixes.length; i++) {
56
+            var fieldSelector = "[name=" + prefixes[i] + name + "]";
57
+            var field = $(fieldSelector);
58
+
59
+            if (field.length) {
60
+                return field;
61
+            }
62
+        }
63
+
64
+        return $();
65
+    };
66
+
67
+    /**
68
+     * Get field value which is put to forwarded dictionary
69
+     * @param field the field
70
+     * @returns forwarded value
71
+     */
72
+    yl.getValueFromField = function(field) {
73
+        var strategy = getForwardStrategy(field);
74
+        var serializedField = $(field).serializeArray();
75
+
76
+        if ((serializedField == false) && ($(field).prop('disabled'))) {
77
+            $(field).prop('disabled', false);
78
+            serializedField = $(field).serializeArray();
79
+            $(field).prop('disabled', true);
80
+        }
81
+
82
+        var getSerializedFieldElementAt = function (index) {
83
+            // Return serializedField[index]
84
+            // or null if something went wrong
85
+            if (serializedField.length > index) {
86
+                return serializedField[index];
87
+            } else {
88
+                return null;
89
+            }
90
+        };
91
+
92
+        var getValueOf = function (elem) {
93
+            // Return elem.value
94
+            // or null if something went wrong
95
+            if (elem.hasOwnProperty("value") &&
96
+                elem.value !== undefined
97
+            ) {
98
+                return elem.value;
99
+            } else {
100
+                return null;
101
+            }
102
+        };
103
+
104
+        var getSerializedFieldValueAt = function (index) {
105
+            // Return serializedField[index].value
106
+            // or null if something went wrong
107
+            var elem = getSerializedFieldElementAt(index);
108
+            if (elem !== null) {
109
+                return getValueOf(elem);
110
+            } else {
111
+                return null;
112
+            }
113
+        };
114
+
115
+        if (strategy === "multiple") {
116
+            return serializedField.map(
117
+                function (item) {
118
+                    return getValueOf(item);
119
+                }
120
+            );
121
+        } else if (strategy === "exists") {
122
+            return serializedField.length > 0;
123
+        } else {
124
+            return getSerializedFieldValueAt(0);
125
+        }
126
+    };
127
+
128
+    yl.getForwards = function(element) {
129
+        var forwardElem,
130
+            forwardList,
131
+            forwardedData,
132
+            divSelector,
133
+            form;
134
+        divSelector = "div.dal-forward-conf#dal-forward-conf-for-" +
135
+                element.attr("id") + ", " +
136
+                "div.dal-forward-conf#dal-forward-conf-for_" +
137
+                element.attr("id");
138
+        form = element.length > 0 ? $(element[0].form) : $();
139
+
140
+        forwardElem =
141
+            form.find(divSelector).find('script');
142
+        if (forwardElem.length === 0) {
143
+            return;
144
+        }
145
+        try {
146
+            forwardList = JSON.parse(forwardElem.text());
147
+        } catch (e) {
148
+            return;
149
+        }
150
+
151
+        if (!Array.isArray(forwardList)) {
152
+            return;
153
+        }
154
+
155
+        forwardedData = {};
156
+
157
+        $.each(forwardList, function(ix, field) {
158
+            var srcName, dstName;
159
+            if (field.type === "const") {
160
+                forwardedData[field.dst] = field.val;
161
+            } else if (field.type === "self") {
162
+                if (field.hasOwnProperty("dst")) {
163
+                    dstName = field.dst;
164
+                } else {
165
+                    dstName = "self";
166
+                }
167
+                forwardedData[dstName] = yl.getValueFromField(element);
168
+            } else if (field.type === "field") {
169
+                srcName = field.src;
170
+                if (field.hasOwnProperty("dst")) {
171
+                    dstName = field.dst;
172
+                } else {
173
+                    dstName = srcName;
174
+                }
175
+                var forwardedField = yl.getFieldRelativeTo(element, srcName);
176
+
177
+                if (!forwardedField.length) {
178
+                    return;
179
+                }
180
+
181
+                forwardedData[dstName] = yl.getValueFromField(forwardedField);
182
+            } else if (field.type === "javascript") {
183
+                var handler = yl.getForwardHandler(field.handler);
184
+                forwardedData[field.dst || field.handler] = handler(element);
185
+            }
186
+
187
+        });
188
+        return JSON.stringify(forwardedData);
189
+    };
190
+
191
+})(yl.jQuery, yl);

+ 36 - 0
app/staticfile/autocomplete_light/jquery.init.js

@@ -0,0 +1,36 @@
1
+var yl = yl || {};
2
+if (typeof django !== 'undefined' && typeof django.jQuery !== 'undefined') {
3
+    // If django.jQuery is already defined, use it.
4
+    yl.jQuery = django.jQuery;
5
+}
6
+else {
7
+    // We include jquery itself in our widget's media, because we need it.
8
+    // Normally, we expect our widget's reference to admin/js/vendor/jquery/jquery.js
9
+    // to be skipped, because django's own code has already included it.
10
+    // However, if django.jQuery is NOT defined, we know that jquery was not
11
+    // included before we did it ourselves. This can happen if we're not being
12
+    // rendered in a django admin form.
13
+    // However, someone ELSE'S jQuery may have been included before ours, in
14
+    // which case we must ensure that our jquery doesn't override theirs, since
15
+    // it might be a newer version that other code on the page relies on.
16
+    // Thus, we must run jQuery.noConflict(true) here to move our jQuery out of
17
+    // the way.
18
+    yl.jQuery = jQuery.noConflict(true);
19
+}
20
+
21
+// In addition to all of this, we must ensure that the global jQuery and $ are
22
+// defined, because Select2 requires that. jQuery will only be undefined at
23
+// this point if only we or django included it.
24
+if (typeof jQuery === 'undefined') {
25
+    jQuery = yl.jQuery;
26
+    $ = yl.jQuery;
27
+}
28
+else {
29
+    // jQuery IS still defined, which means someone else also included jQuery.
30
+    // In this situation, we need to store the old jQuery in a
31
+    // temp variable, set the global jQuery to our yl.jQuery, then let select2
32
+    // set itself up. We restore the global jQuery to its original value in
33
+    // jquery.post-setup.js.
34
+    dal_jquery_backup = jQuery.noConflict(true);
35
+    jQuery = yl.jQuery;
36
+}

+ 7 - 0
app/staticfile/autocomplete_light/jquery.post-setup.js

@@ -0,0 +1,7 @@
1
+if (typeof dal_jquery_backup !== 'undefined') {
2
+    // We made a backup of the original global jQuery before forcing it to our
3
+    // yl.jQuery value. Now that select2 has been set up, we need to restore
4
+    // our backup to its rightful place.
5
+    jQuery = dal_jquery_backup;
6
+    $ = dal_jquery_backup;
7
+}

+ 14 - 0
app/staticfile/autocomplete_light/select2.css

@@ -0,0 +1,14 @@
1
+.select2-container {
2
+    min-width: 20em;
3
+}
4
+
5
+ul li.select2-selection__choice,
6
+ul li.select2-search {
7
+    /* Cancel out django's style */
8
+    list-style-type: none;
9
+}
10
+
11
+.errors .select2-selection {
12
+    /* Highlight select box with error */
13
+    border-color: #ba2121;
14
+}

+ 122 - 0
app/staticfile/autocomplete_light/select2.js

@@ -0,0 +1,122 @@
1
+;(function ($) {
2
+    if (window.__dal__initListenerIsSet)
3
+        return;
4
+
5
+    $(document).on('autocompleteLightInitialize', '[data-autocomplete-light-function=select2]', function() {
6
+        var element = $(this);
7
+
8
+        // Templating helper
9
+        function template(text, is_html) {
10
+            if (is_html) {
11
+                var $result = $('<span>');
12
+                $result.html(text);
13
+                return $result;
14
+            } else {
15
+                return text;
16
+            }
17
+        }
18
+
19
+        function result_template(item) {
20
+            var text = template(item.text,
21
+                element.attr('data-html') !== undefined || element.attr('data-result-html') !== undefined
22
+            );
23
+
24
+            if (item.create_id) {
25
+                return $('<span></span>').text(text).addClass('dal-create')
26
+            } else {
27
+                return text
28
+            }
29
+        }
30
+
31
+        function selected_template(item) {
32
+            if (item.selected_text !== undefined) {
33
+                return template(item.selected_text,
34
+                    element.attr('data-html') !== undefined || element.attr('data-selected-html') !== undefined
35
+                );
36
+            } else {
37
+                return result_template(item);
38
+            }
39
+            return
40
+        }
41
+
42
+        var ajax = null;
43
+        if ($(this).attr('data-autocomplete-light-url')) {
44
+            ajax = {
45
+                url: $(this).attr('data-autocomplete-light-url'),
46
+                dataType: 'json',
47
+                delay: 250,
48
+
49
+                data: function (params) {
50
+                    var data = {
51
+                        q: params.term, // search term
52
+                        page: params.page,
53
+                        create: element.attr('data-autocomplete-light-create') && !element.attr('data-tags'),
54
+                        forward: yl.getForwards(element)
55
+                    };
56
+
57
+                    return data;
58
+                },
59
+                processResults: function (data, page) {
60
+                    if (element.attr('data-tags')) {
61
+                        $.each(data.results, function(index, value) {
62
+                            value.id = value.text;
63
+                        });
64
+                    }
65
+
66
+                    return data;
67
+                },
68
+                cache: true
69
+            };
70
+        }
71
+
72
+        $(this).select2({
73
+            tokenSeparators: element.attr('data-tags') ? [','] : null,
74
+            debug: true,
75
+            containerCssClass: ':all:',
76
+            placeholder: element.attr('data-placeholder') || '',
77
+            language: element.attr('data-autocomplete-light-language'),
78
+            minimumInputLength: element.attr('data-minimum-input-length') || 0,
79
+            allowClear: ! $(this).is('[required]'),
80
+            templateResult: result_template,
81
+            templateSelection: selected_template,
82
+            ajax: ajax,
83
+            tags: Boolean(element.attr('data-tags')),
84
+        });
85
+
86
+        $(this).on('select2:selecting', function (e) {
87
+            var data = e.params.args.data;
88
+
89
+            if (data.create_id !== true)
90
+                return;
91
+
92
+            e.preventDefault();
93
+
94
+            var select = $(this);
95
+
96
+            $.ajax({
97
+                url: $(this).attr('data-autocomplete-light-url'),
98
+                type: 'POST',
99
+                dataType: 'json',
100
+                data: {
101
+                    text: data.id,
102
+                    forward: yl.getForwards($(this))
103
+                },
104
+                beforeSend: function(xhr, settings) {
105
+                    xhr.setRequestHeader("X-CSRFToken", document.csrftoken);
106
+                },
107
+                success: function(data, textStatus, jqXHR ) {
108
+                    select.append(
109
+                        $('<option>', {value: data.id, text: data.text, selected: true})
110
+                    );
111
+                    select.trigger('change');
112
+                    select.select2('close');
113
+                }
114
+            });
115
+        });
116
+
117
+    });
118
+    window.__dal__initListenerIsSet = true;
119
+    $('[data-autocomplete-light-function=select2]:not([id*="__prefix__"])').each(function() {
120
+        window.__dal__initialize(this);
121
+    });
122
+})(yl.jQuery);

BIN
app/staticfile/img/heartbeat.png


+ 22 - 0
app/staticfile/import_export/action_formats.js

@@ -0,0 +1,22 @@
1
+(function($) {
2
+  $(document).ready(function() {
3
+    var $actionsSelect, $formatsElement;
4
+    if ($('body').hasClass('grp-change-list')) {
5
+        // using grappelli
6
+        $actionsSelect = $('#grp-changelist-form select[name="action"]');
7
+        $formatsElement = $('#grp-changelist-form select[name="file_format"]');
8
+    } else {
9
+        // using default admin
10
+        $actionsSelect = $('#changelist-form select[name="action"]');
11
+        $formatsElement = $('#changelist-form select[name="file_format"]').parent();
12
+    }
13
+    $actionsSelect.change(function() {
14
+      if ($(this).val() === 'export_admin_action') {
15
+        $formatsElement.show();
16
+      } else {
17
+        $formatsElement.hide();
18
+      }
19
+    });
20
+    $actionsSelect.change();
21
+  });
22
+})(django.jQuery);

+ 81 - 0
app/staticfile/import_export/import.css

@@ -0,0 +1,81 @@
1
+.import-preview .errors {
2
+  position: relative;
3
+}
4
+
5
+.validation-error-count {
6
+  display: inline-block;
7
+  background-color: #e40000;
8
+  border-radius: 6px;
9
+  color: white;
10
+  font-size: 0.9em;
11
+  position: relative;
12
+  font-weight: bold;
13
+  margin-top: -2px;
14
+  padding: 0.2em 0.4em;
15
+}
16
+
17
+.validation-error-container {
18
+  position: absolute;
19
+  opacity: 0;
20
+  pointer-events: none;
21
+  background-color: #ffc1c1;
22
+  padding: 14px 15px 10px;
23
+  top: 25px;
24
+  margin: 0 0 20px 0;
25
+  width: 200px;
26
+  z-index: 2;
27
+}
28
+
29
+table.import-preview tr.skip {
30
+  background-color: #d2d2d2;
31
+}
32
+
33
+table.import-preview tr.new {
34
+  background-color: #bdd8b2;
35
+}
36
+
37
+table.import-preview tr.delete {
38
+  background-color: #f9bebf;
39
+}
40
+
41
+table.import-preview tr.update {
42
+  background-color: #fdfdcf;
43
+}
44
+
45
+.import-preview td:hover .validation-error-count {
46
+  z-index: 3;
47
+}
48
+.import-preview td:hover .validation-error-container {
49
+  opacity: 1;
50
+  pointer-events: auto;
51
+}
52
+
53
+.validation-error-list {
54
+  margin: 0;
55
+  padding: 0;
56
+}
57
+
58
+.validation-error-list li {
59
+  list-style: none;
60
+  margin: 0;
61
+}
62
+
63
+.validation-error-list > li > ul {
64
+  margin: 8px 0;
65
+  padding: 0;
66
+}
67
+
68
+.validation-error-list > li > ul > li {
69
+  padding: 0;
70
+  margin: 0 0 10px;
71
+  line-height: 1.28em;
72
+}
73
+
74
+.validation-error-field-label {
75
+  display: block;
76
+  border-bottom: 1px solid #e40000;
77
+  color: #e40000;
78
+  text-transform: uppercase;
79
+  font-weight: bold;
80
+  font-size: 0.85em;
81
+}

+ 15 - 0
app/staticfile/js/main.js

@@ -0,0 +1,15 @@
1
+$(function(){
2
+    $("#currentLocationBtn").click(function(){
3
+        if ("geolocation" in navigator){ //check geolocation available
4
+            //try to get user current location using getCurrentPosition() method
5
+            console.log("current location");
6
+            navigator.geolocation.getCurrentPosition(function(position){
7
+                console.log("xxxx");
8
+                $("#geoText").val(position.coords.latitude+","+position.coords.longitude );
9
+
10
+            });
11
+        }else{
12
+            console.log("Browser doesn't support geolocation!");
13
+        }
14
+    });
15
+});

+ 262 - 0
app/staticfile/vendor/select2/Gruntfile.js

@@ -0,0 +1,262 @@
1
+const sass = require('node-sass');
2
+
3
+module.exports = function (grunt) {
4
+  // Full list of files that must be included by RequireJS
5
+  includes = [
6
+    'jquery.select2',
7
+    'almond',
8
+
9
+    'jquery-mousewheel' // shimmed for non-full builds
10
+  ];
11
+
12
+  fullIncludes = [
13
+    'jquery',
14
+
15
+    'select2/compat/containerCss',
16
+    'select2/compat/dropdownCss',
17
+
18
+    'select2/compat/initSelection',
19
+    'select2/compat/inputData',
20
+    'select2/compat/matcher',
21
+    'select2/compat/query',
22
+
23
+    'select2/dropdown/attachContainer',
24
+    'select2/dropdown/stopPropagation',
25
+
26
+    'select2/selection/stopPropagation'
27
+  ].concat(includes);
28
+
29
+  var i18nModules = [];
30
+  var i18nPaths = {};
31
+
32
+  var i18nFiles = grunt.file.expand({
33
+    cwd: 'src/js'
34
+  }, 'select2/i18n/*.js');
35
+
36
+  var testFiles = grunt.file.expand('tests/**/*.html');
37
+  var testUrls = testFiles.map(function (filePath) {
38
+    return 'http://localhost:9999/' + filePath;
39
+  });
40
+
41
+  var testBuildNumber = "unknown";
42
+
43
+  if (process.env.TRAVIS_JOB_ID) {
44
+    testBuildNumber = "travis-" + process.env.TRAVIS_JOB_ID;
45
+  } else {
46
+    var currentTime = new Date();
47
+
48
+    testBuildNumber = "manual-" + currentTime.getTime();
49
+  }
50
+
51
+  for (var i = 0; i < i18nFiles.length; i++) {
52
+    var file = i18nFiles[i];
53
+    var name = file.split('.')[0];
54
+
55
+    i18nModules.push({
56
+      name: name
57
+    });
58
+
59
+    i18nPaths[name] = '../../' + name;
60
+  }
61
+
62
+  var minifiedBanner = '/*! Select2 <%= package.version %> | https://github.com/select2/select2/blob/master/LICENSE.md */';
63
+
64
+  grunt.initConfig({
65
+    package: grunt.file.readJSON('package.json'),
66
+
67
+    concat: {
68
+      'dist': {
69
+        options: {
70
+          banner: grunt.file.read('src/js/wrapper.start.js'),
71
+        },
72
+        src: [
73
+          'dist/js/select2.js',
74
+          'src/js/wrapper.end.js'
75
+        ],
76
+        dest: 'dist/js/select2.js'
77
+      },
78
+      'dist.full': {
79
+        options: {
80
+          banner: grunt.file.read('src/js/wrapper.start.js'),
81
+        },
82
+        src: [
83
+          'dist/js/select2.full.js',
84
+          'src/js/wrapper.end.js'
85
+        ],
86
+        dest: 'dist/js/select2.full.js'
87
+      }
88
+    },
89
+
90
+    connect: {
91
+      tests: {
92
+        options: {
93
+          base: '.',
94
+          hostname: '127.0.0.1',
95
+          port: 9999
96
+        }
97
+      }
98
+    },
99
+
100
+    uglify: {
101
+      'dist': {
102
+        src: 'dist/js/select2.js',
103
+        dest: 'dist/js/select2.min.js',
104
+        options: {
105
+          banner: minifiedBanner
106
+        }
107
+      },
108
+      'dist.full': {
109
+        src: 'dist/js/select2.full.js',
110
+        dest: 'dist/js/select2.full.min.js',
111
+        options: {
112
+          banner: minifiedBanner
113
+        }
114
+      }
115
+    },
116
+
117
+    qunit: {
118
+      all: {
119
+        options: {
120
+          urls: testUrls
121
+        }
122
+      }
123
+    },
124
+
125
+    jshint: {
126
+      options: {
127
+        jshintrc: true,
128
+        reporterOutput: ''
129
+      },
130
+      code: {
131
+        src: ['src/js/**/*.js']
132
+      },
133
+      tests: {
134
+        src: ['tests/**/*.js']
135
+      }
136
+    },
137
+
138
+    sass: {
139
+      dist: {
140
+        options: {
141
+          implementation: sass,
142
+          outputStyle: 'compressed'
143
+        },
144
+        files: {
145
+          'dist/css/select2.min.css': [
146
+            'src/scss/core.scss',
147
+            'src/scss/theme/default/layout.css'
148
+          ]
149
+        }
150
+      },
151
+      dev: {
152
+        options: {
153
+          implementation: sass,
154
+          outputStyle: 'nested'
155
+        },
156
+        files: {
157
+          'dist/css/select2.css': [
158
+            'src/scss/core.scss',
159
+            'src/scss/theme/default/layout.css'
160
+          ]
161
+        }
162
+      }
163
+    },
164
+
165
+    requirejs: {
166
+      'dist': {
167
+        options: {
168
+          baseUrl: 'src/js',
169
+          optimize: 'none',
170
+          name: 'select2/core',
171
+          out: 'dist/js/select2.js',
172
+          include: includes,
173
+          namespace: 'S2',
174
+          paths: {
175
+            'almond': require.resolve('almond').slice(0, -3),
176
+            'jquery': 'jquery.shim',
177
+            'jquery-mousewheel': 'jquery.mousewheel.shim'
178
+          },
179
+          wrap: {
180
+            startFile: 'src/js/banner.start.js',
181
+            endFile: 'src/js/banner.end.js'
182
+          }
183
+        }
184
+      },
185
+      'dist.full': {
186
+        options: {
187
+          baseUrl: 'src/js',
188
+          optimize: 'none',
189
+          name: 'select2/core',
190
+          out: 'dist/js/select2.full.js',
191
+          include: fullIncludes,
192
+          namespace: 'S2',
193
+          paths: {
194
+            'almond': require.resolve('almond').slice(0, -3),
195
+            'jquery': 'jquery.shim',
196
+            'jquery-mousewheel': require.resolve('jquery-mousewheel').slice(0, -3)
197
+          },
198
+          wrap: {
199
+            startFile: 'src/js/banner.start.js',
200
+            endFile: 'src/js/banner.end.js'
201
+          }
202
+        }
203
+      },
204
+      'i18n': {
205
+        options: {
206
+          baseUrl: 'src/js/select2/i18n',
207
+          dir: 'dist/js/i18n',
208
+          paths: i18nPaths,
209
+          modules: i18nModules,
210
+          namespace: 'S2',
211
+          wrap: {
212
+            start: minifiedBanner + grunt.file.read('src/js/banner.start.js'),
213
+            end: grunt.file.read('src/js/banner.end.js')
214
+          }
215
+        }
216
+      }
217
+    },
218
+
219
+    watch: {
220
+      js: {
221
+        files: [
222
+          'src/js/select2/**/*.js',
223
+          'tests/**/*.js'
224
+        ],
225
+        tasks: [
226
+          'compile',
227
+          'test',
228
+          'minify'
229
+        ]
230
+      },
231
+      css: {
232
+        files: [
233
+          'src/scss/**/*.scss'
234
+        ],
235
+        tasks: [
236
+          'compile',
237
+          'minify'
238
+        ]
239
+      }
240
+    }
241
+  });
242
+
243
+  grunt.loadNpmTasks('grunt-contrib-concat');
244
+  grunt.loadNpmTasks('grunt-contrib-connect');
245
+  grunt.loadNpmTasks('grunt-contrib-jshint');
246
+  grunt.loadNpmTasks('grunt-contrib-qunit');
247
+  grunt.loadNpmTasks('grunt-contrib-requirejs');
248
+  grunt.loadNpmTasks('grunt-contrib-uglify');
249
+  grunt.loadNpmTasks('grunt-contrib-watch');
250
+
251
+  grunt.loadNpmTasks('grunt-sass');
252
+
253
+  grunt.registerTask('default', ['compile', 'test', 'minify']);
254
+
255
+  grunt.registerTask('compile', [
256
+    'requirejs:dist', 'requirejs:dist.full', 'requirejs:i18n',
257
+    'concat:dist', 'concat:dist.full',
258
+    'sass:dev'
259
+  ]);
260
+  grunt.registerTask('minify', ['uglify', 'sass:dist']);
261
+  grunt.registerTask('test', ['connect:tests', 'qunit', 'jshint']);
262
+};

+ 13 - 0
app/staticfile/vendor/select2/bower.json

@@ -0,0 +1,13 @@
1
+{
2
+    "name": "select2",
3
+    "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
4
+    "main": [
5
+        "dist/js/select2.js",
6
+        "src/scss/core.scss"
7
+    ],
8
+    "license": "MIT",
9
+    "repository": {
10
+        "type": "git",
11
+        "url": "git@github.com:select2/select2.git"
12
+    }
13
+}

+ 19 - 0
app/staticfile/vendor/select2/component.json

@@ -0,0 +1,19 @@
1
+{
2
+  "name": "select2",
3
+  "repo": "select/select2",
4
+  "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
5
+  "version": "4.0.7",
6
+  "demo": "https://select2.org/",
7
+  "keywords": [
8
+    "jquery"
9
+  ],
10
+  "main": "dist/js/select2.js",
11
+  "styles": [
12
+    "dist/css/select2.css"
13
+  ],
14
+  "scripts": [
15
+    "dist/js/select2.js",
16
+    "dist/js/i18n/*.js"
17
+  ],
18
+  "license": "MIT"
19
+}

+ 22 - 0
app/staticfile/vendor/select2/composer.json

@@ -0,0 +1,22 @@
1
+{
2
+  "name": "select2/select2",
3
+  "description": "Select2 is a jQuery based replacement for select boxes.",
4
+  "type": "component",
5
+  "homepage": "https://select2.org/",
6
+  "license": "MIT",
7
+  "extra": {
8
+    "component": {
9
+      "scripts": [
10
+        "dist/js/select2.js"
11
+      ],
12
+      "styles": [
13
+        "dist/css/select2.css"
14
+      ],
15
+      "files": [
16
+        "dist/js/select2.js",
17
+        "dist/js/i18n/*.js",
18
+        "dist/css/select2.css"
19
+      ]
20
+    }
21
+  }
22
+}

+ 484 - 0
app/staticfile/vendor/select2/dist/css/select2.css

@@ -0,0 +1,484 @@
1
+.select2-container {
2
+  box-sizing: border-box;
3
+  display: inline-block;
4
+  margin: 0;
5
+  position: relative;
6
+  vertical-align: middle; }
7
+  .select2-container .select2-selection--single {
8
+    box-sizing: border-box;
9
+    cursor: pointer;
10
+    display: block;
11
+    height: 28px;
12
+    user-select: none;
13
+    -webkit-user-select: none; }
14
+    .select2-container .select2-selection--single .select2-selection__rendered {
15
+      display: block;
16
+      padding-left: 8px;
17
+      padding-right: 20px;
18
+      overflow: hidden;
19
+      text-overflow: ellipsis;
20
+      white-space: nowrap; }
21
+    .select2-container .select2-selection--single .select2-selection__clear {
22
+      position: relative; }
23
+  .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
24
+    padding-right: 8px;
25
+    padding-left: 20px; }
26
+  .select2-container .select2-selection--multiple {
27
+    box-sizing: border-box;
28
+    cursor: pointer;
29
+    display: block;
30
+    min-height: 32px;
31
+    user-select: none;
32
+    -webkit-user-select: none; }
33
+    .select2-container .select2-selection--multiple .select2-selection__rendered {
34
+      display: inline-block;
35
+      overflow: hidden;
36
+      padding-left: 8px;
37
+      text-overflow: ellipsis;
38
+      white-space: nowrap; }
39
+  .select2-container .select2-search--inline {
40
+    float: left; }
41
+    .select2-container .select2-search--inline .select2-search__field {
42
+      box-sizing: border-box;
43
+      border: none;
44
+      font-size: 100%;
45
+      margin-top: 5px;
46
+      padding: 0; }
47
+      .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
48
+        -webkit-appearance: none; }
49
+
50
+.select2-dropdown {
51
+  background-color: white;
52
+  border: 1px solid #aaa;
53
+  border-radius: 4px;
54
+  box-sizing: border-box;
55
+  display: block;
56
+  position: absolute;
57
+  left: -100000px;
58
+  width: 100%;
59
+  z-index: 1051; }
60
+
61
+.select2-results {
62
+  display: block; }
63
+
64
+.select2-results__options {
65
+  list-style: none;
66
+  margin: 0;
67
+  padding: 0; }
68
+
69
+.select2-results__option {
70
+  padding: 6px;
71
+  user-select: none;
72
+  -webkit-user-select: none; }
73
+  .select2-results__option[aria-selected] {
74
+    cursor: pointer; }
75
+
76
+.select2-container--open .select2-dropdown {
77
+  left: 0; }
78
+
79
+.select2-container--open .select2-dropdown--above {
80
+  border-bottom: none;
81
+  border-bottom-left-radius: 0;
82
+  border-bottom-right-radius: 0; }
83
+
84
+.select2-container--open .select2-dropdown--below {
85
+  border-top: none;
86
+  border-top-left-radius: 0;
87
+  border-top-right-radius: 0; }
88
+
89
+.select2-search--dropdown {
90
+  display: block;
91
+  padding: 4px; }
92
+  .select2-search--dropdown .select2-search__field {
93
+    padding: 4px;
94
+    width: 100%;
95
+    box-sizing: border-box; }
96
+    .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
97
+      -webkit-appearance: none; }
98
+  .select2-search--dropdown.select2-search--hide {
99
+    display: none; }
100
+
101
+.select2-close-mask {
102
+  border: 0;
103
+  margin: 0;
104
+  padding: 0;
105
+  display: block;
106
+  position: fixed;
107
+  left: 0;
108
+  top: 0;
109
+  min-height: 100%;
110
+  min-width: 100%;
111
+  height: auto;
112
+  width: auto;
113
+  opacity: 0;
114
+  z-index: 99;
115
+  background-color: #fff;
116
+  filter: alpha(opacity=0); }
117
+
118
+.select2-hidden-accessible {
119
+  border: 0 !important;
120
+  clip: rect(0 0 0 0) !important;
121
+  -webkit-clip-path: inset(50%) !important;
122
+  clip-path: inset(50%) !important;
123
+  height: 1px !important;
124
+  overflow: hidden !important;
125
+  padding: 0 !important;
126
+  position: absolute !important;
127
+  width: 1px !important;
128
+  white-space: nowrap !important; }
129
+
130
+.select2-container--default .select2-selection--single {
131
+  background-color: #fff;
132
+  border: 1px solid #aaa;
133
+  border-radius: 4px; }
134
+  .select2-container--default .select2-selection--single .select2-selection__rendered {
135
+    color: #444;
136
+    line-height: 28px; }
137
+  .select2-container--default .select2-selection--single .select2-selection__clear {
138
+    cursor: pointer;
139
+    float: right;
140
+    font-weight: bold; }
141
+  .select2-container--default .select2-selection--single .select2-selection__placeholder {
142
+    color: #999; }
143
+  .select2-container--default .select2-selection--single .select2-selection__arrow {
144
+    height: 26px;
145
+    position: absolute;
146
+    top: 1px;
147
+    right: 1px;
148
+    width: 20px; }
149
+    .select2-container--default .select2-selection--single .select2-selection__arrow b {
150
+      border-color: #888 transparent transparent transparent;
151
+      border-style: solid;
152
+      border-width: 5px 4px 0 4px;
153
+      height: 0;
154
+      left: 50%;
155
+      margin-left: -4px;
156
+      margin-top: -2px;
157
+      position: absolute;
158
+      top: 50%;
159
+      width: 0; }
160
+
161
+.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
162
+  float: left; }
163
+
164
+.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
165
+  left: 1px;
166
+  right: auto; }
167
+
168
+.select2-container--default.select2-container--disabled .select2-selection--single {
169
+  background-color: #eee;
170
+  cursor: default; }
171
+  .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
172
+    display: none; }
173
+
174
+.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
175
+  border-color: transparent transparent #888 transparent;
176
+  border-width: 0 4px 5px 4px; }
177
+
178
+.select2-container--default .select2-selection--multiple {
179
+  background-color: white;
180
+  border: 1px solid #aaa;
181
+  border-radius: 4px;
182
+  cursor: text; }
183
+  .select2-container--default .select2-selection--multiple .select2-selection__rendered {
184
+    box-sizing: border-box;
185
+    list-style: none;
186
+    margin: 0;
187
+    padding: 0 5px;
188
+    width: 100%; }
189
+    .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
190
+      list-style: none; }
191
+  .select2-container--default .select2-selection--multiple .select2-selection__placeholder {
192
+    color: #999;
193
+    margin-top: 5px;
194
+    float: left; }
195
+  .select2-container--default .select2-selection--multiple .select2-selection__clear {
196
+    cursor: pointer;
197
+    float: right;
198
+    font-weight: bold;
199
+    margin-top: 5px;
200
+    margin-right: 10px; }
201
+  .select2-container--default .select2-selection--multiple .select2-selection__choice {
202
+    background-color: #e4e4e4;
203
+    border: 1px solid #aaa;
204
+    border-radius: 4px;
205
+    cursor: default;
206
+    float: left;
207
+    margin-right: 5px;
208
+    margin-top: 5px;
209
+    padding: 0 5px; }
210
+  .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
211
+    color: #999;
212
+    cursor: pointer;
213
+    display: inline-block;
214
+    font-weight: bold;
215
+    margin-right: 2px; }
216
+    .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
217
+      color: #333; }
218
+
219
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
220
+  float: right; }
221
+
222
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
223
+  margin-left: 5px;
224
+  margin-right: auto; }
225
+
226
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
227
+  margin-left: 2px;
228
+  margin-right: auto; }
229
+
230
+.select2-container--default.select2-container--focus .select2-selection--multiple {
231
+  border: solid black 1px;
232
+  outline: 0; }
233
+
234
+.select2-container--default.select2-container--disabled .select2-selection--multiple {
235
+  background-color: #eee;
236
+  cursor: default; }
237
+
238
+.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
239
+  display: none; }
240
+
241
+.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
242
+  border-top-left-radius: 0;
243
+  border-top-right-radius: 0; }
244
+
245
+.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
246
+  border-bottom-left-radius: 0;
247
+  border-bottom-right-radius: 0; }
248
+
249
+.select2-container--default .select2-search--dropdown .select2-search__field {
250
+  border: 1px solid #aaa; }
251
+
252
+.select2-container--default .select2-search--inline .select2-search__field {
253
+  background: transparent;
254
+  border: none;
255
+  outline: 0;
256
+  box-shadow: none;
257
+  -webkit-appearance: textfield; }
258
+
259
+.select2-container--default .select2-results > .select2-results__options {
260
+  max-height: 200px;
261
+  overflow-y: auto; }
262
+
263
+.select2-container--default .select2-results__option[role=group] {
264
+  padding: 0; }
265
+
266
+.select2-container--default .select2-results__option[aria-disabled=true] {
267
+  color: #999; }
268
+
269
+.select2-container--default .select2-results__option[aria-selected=true] {
270
+  background-color: #ddd; }
271
+
272
+.select2-container--default .select2-results__option .select2-results__option {
273
+  padding-left: 1em; }
274
+  .select2-container--default .select2-results__option .select2-results__option .select2-results__group {
275
+    padding-left: 0; }
276
+  .select2-container--default .select2-results__option .select2-results__option .select2-results__option {
277
+    margin-left: -1em;
278
+    padding-left: 2em; }
279
+    .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
280
+      margin-left: -2em;
281
+      padding-left: 3em; }
282
+      .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
283
+        margin-left: -3em;
284
+        padding-left: 4em; }
285
+        .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
286
+          margin-left: -4em;
287
+          padding-left: 5em; }
288
+          .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
289
+            margin-left: -5em;
290
+            padding-left: 6em; }
291
+
292
+.select2-container--default .select2-results__option--highlighted[aria-selected] {
293
+  background-color: #5897fb;
294
+  color: white; }
295
+
296
+.select2-container--default .select2-results__group {
297
+  cursor: default;
298
+  display: block;
299
+  padding: 6px; }
300
+
301
+.select2-container--classic .select2-selection--single {
302
+  background-color: #f7f7f7;
303
+  border: 1px solid #aaa;
304
+  border-radius: 4px;
305
+  outline: 0;
306
+  background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
307
+  background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
308
+  background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
309
+  background-repeat: repeat-x;
310
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
311
+  .select2-container--classic .select2-selection--single:focus {
312
+    border: 1px solid #5897fb; }
313
+  .select2-container--classic .select2-selection--single .select2-selection__rendered {
314
+    color: #444;
315
+    line-height: 28px; }
316
+  .select2-container--classic .select2-selection--single .select2-selection__clear {
317
+    cursor: pointer;
318
+    float: right;
319
+    font-weight: bold;
320
+    margin-right: 10px; }
321
+  .select2-container--classic .select2-selection--single .select2-selection__placeholder {
322
+    color: #999; }
323
+  .select2-container--classic .select2-selection--single .select2-selection__arrow {
324
+    background-color: #ddd;
325
+    border: none;
326
+    border-left: 1px solid #aaa;
327
+    border-top-right-radius: 4px;
328
+    border-bottom-right-radius: 4px;
329
+    height: 26px;
330
+    position: absolute;
331
+    top: 1px;
332
+    right: 1px;
333
+    width: 20px;
334
+    background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
335
+    background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
336
+    background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
337
+    background-repeat: repeat-x;
338
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
339
+    .select2-container--classic .select2-selection--single .select2-selection__arrow b {
340
+      border-color: #888 transparent transparent transparent;
341
+      border-style: solid;
342
+      border-width: 5px 4px 0 4px;
343
+      height: 0;
344
+      left: 50%;
345
+      margin-left: -4px;
346
+      margin-top: -2px;
347
+      position: absolute;
348
+      top: 50%;
349
+      width: 0; }
350
+
351
+.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
352
+  float: left; }
353
+
354
+.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
355
+  border: none;
356
+  border-right: 1px solid #aaa;
357
+  border-radius: 0;
358
+  border-top-left-radius: 4px;
359
+  border-bottom-left-radius: 4px;
360
+  left: 1px;
361
+  right: auto; }
362
+
363
+.select2-container--classic.select2-container--open .select2-selection--single {
364
+  border: 1px solid #5897fb; }
365
+  .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
366
+    background: transparent;
367
+    border: none; }
368
+    .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
369
+      border-color: transparent transparent #888 transparent;
370
+      border-width: 0 4px 5px 4px; }
371
+
372
+.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
373
+  border-top: none;
374
+  border-top-left-radius: 0;
375
+  border-top-right-radius: 0;
376
+  background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
377
+  background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
378
+  background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
379
+  background-repeat: repeat-x;
380
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
381
+
382
+.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
383
+  border-bottom: none;
384
+  border-bottom-left-radius: 0;
385
+  border-bottom-right-radius: 0;
386
+  background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
387
+  background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
388
+  background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
389
+  background-repeat: repeat-x;
390
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
391
+
392
+.select2-container--classic .select2-selection--multiple {
393
+  background-color: white;
394
+  border: 1px solid #aaa;
395
+  border-radius: 4px;
396
+  cursor: text;
397
+  outline: 0; }
398
+  .select2-container--classic .select2-selection--multiple:focus {
399
+    border: 1px solid #5897fb; }
400
+  .select2-container--classic .select2-selection--multiple .select2-selection__rendered {
401
+    list-style: none;
402
+    margin: 0;
403
+    padding: 0 5px; }
404
+  .select2-container--classic .select2-selection--multiple .select2-selection__clear {
405
+    display: none; }
406
+  .select2-container--classic .select2-selection--multiple .select2-selection__choice {
407
+    background-color: #e4e4e4;
408
+    border: 1px solid #aaa;
409
+    border-radius: 4px;
410
+    cursor: default;
411
+    float: left;
412
+    margin-right: 5px;
413
+    margin-top: 5px;
414
+    padding: 0 5px; }
415
+  .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
416
+    color: #888;
417
+    cursor: pointer;
418
+    display: inline-block;
419
+    font-weight: bold;
420
+    margin-right: 2px; }
421
+    .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
422
+      color: #555; }
423
+
424
+.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
425
+  float: right;
426
+  margin-left: 5px;
427
+  margin-right: auto; }
428
+
429
+.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
430
+  margin-left: 2px;
431
+  margin-right: auto; }
432
+
433
+.select2-container--classic.select2-container--open .select2-selection--multiple {
434
+  border: 1px solid #5897fb; }
435
+
436
+.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
437
+  border-top: none;
438
+  border-top-left-radius: 0;
439
+  border-top-right-radius: 0; }
440
+
441
+.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
442
+  border-bottom: none;
443
+  border-bottom-left-radius: 0;
444
+  border-bottom-right-radius: 0; }
445
+
446
+.select2-container--classic .select2-search--dropdown .select2-search__field {
447
+  border: 1px solid #aaa;
448
+  outline: 0; }
449
+
450
+.select2-container--classic .select2-search--inline .select2-search__field {
451
+  outline: 0;
452
+  box-shadow: none; }
453
+
454
+.select2-container--classic .select2-dropdown {
455
+  background-color: white;
456
+  border: 1px solid transparent; }
457
+
458
+.select2-container--classic .select2-dropdown--above {
459
+  border-bottom: none; }
460
+
461
+.select2-container--classic .select2-dropdown--below {
462
+  border-top: none; }
463
+
464
+.select2-container--classic .select2-results > .select2-results__options {
465
+  max-height: 200px;
466
+  overflow-y: auto; }
467
+
468
+.select2-container--classic .select2-results__option[role=group] {
469
+  padding: 0; }
470
+
471
+.select2-container--classic .select2-results__option[aria-disabled=true] {
472
+  color: grey; }
473
+
474
+.select2-container--classic .select2-results__option--highlighted[aria-selected] {
475
+  background-color: #3875d7;
476
+  color: white; }
477
+
478
+.select2-container--classic .select2-results__group {
479
+  cursor: default;
480
+  display: block;
481
+  padding: 6px; }
482
+
483
+.select2-container--classic.select2-container--open .select2-dropdown {
484
+  border-color: #5897fb; }

File diff suppressed because it is too large
+ 1 - 0
app/staticfile/vendor/select2/dist/css/select2.min.css


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/af.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/ar.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/az.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/bg.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/bn.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/bs.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/ca.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/cs.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/da.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/de.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/dsb.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/el.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/en.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/es.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/et.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/eu.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/fa.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/fi.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/fr.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/gl.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/he.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/hi.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/hr.js


File diff suppressed because it is too large
+ 3 - 0
app/staticfile/vendor/select2/dist/js/i18n/hsb.js


+ 0 - 0
app/staticfile/vendor/select2/dist/js/i18n/hu.js


Some files were not shown because too many files changed in this diff

tum/coi - Gogs: Simplico Git Service

Sin descripción

measurementexcel.py 56KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763
  1. # -*- coding: utf-8 -*-
  2. from openpyxl import load_workbook
  3. import pyodbc
  4. import time
  5. import sys
  6. from pprint import pprint
  7. import datetime
  8. from openpyxl.styles import NamedStyle, Font, colors, Border, Side
  9. import openpyxl.drawing.text as drawingText
  10. from copy import deepcopy
  11. from openpyxl.chart import LineChart, Reference, Series
  12. from openpyxl.chart.text import RichText
  13. from openpyxl.drawing.text import RichTextProperties,Paragraph,ParagraphProperties, CharacterProperties
  14. import openpyxl.utils as utils
  15. from openpyxl.chart.text import RichText
  16. from shutil import copyfile
  17. from copy import copy
  18. dateStyle = NamedStyle(name='custom_datetime', number_format='DD/MM/YYYY HH:MM:MM')
  19. from openpyxl.styles.numbers import FORMAT_DATE_DATETIME
  20. stdSizeMapColumn = {
  21. "D": "F",
  22. "T": "G",
  23. "H": "H",
  24. "A": "I",
  25. "B": "J",
  26. "C": "K",
  27. "E": "L",
  28. "F": "M",
  29. "G": "N",
  30. "J": "O",
  31. "K": "P",
  32. "L": "Q",
  33. "M": "R",
  34. "N": "S",
  35. "O": "T",
  36. "P": "U",
  37. "U": "V",
  38. "Q": "W",
  39. "R": "X",
  40. "S": "Y",
  41. "W": "Z",
  42. "Y": "AA",
  43. "Z": "AB",
  44. "X1": "AC",
  45. "X2": "AD",
  46. "Thickness": "AE",
  47. "Flatness": "AF",
  48. "FLATNESS": "AF",
  49. "Cen": "AG",
  50. "Weight": "AH",
  51. "Result": "AI",
  52. }
  53. codeMap = {
  54. "001": "D",
  55. "002": "T",
  56. "003": "H",
  57. "02": "P",
  58. "03": "E",
  59. "39": "E",
  60. "04": "W",
  61. "05": "JK",
  62. "06": "F",
  63. "51": "F",
  64. "07": "G",
  65. "B2": "G",
  66. "08": "U",
  67. "09": "M",
  68. "10": "A",
  69. "11": "N",
  70. "12": "J",
  71. "13": "X",
  72. "14": "Flatness",
  73. "15": "K",
  74. "16": "Thickness",
  75. "17": "Q",
  76. "18": "S",
  77. "72": "X",
  78. "61": "U"
  79. }
  80. # Specifying the ODBC driver, server name, database, etc. directly
  81. #cnxn = None
  82. #cursor = None
  83. '''cursor.execute('select * from data_wb')
  84. rows = cursor.fetchall()
  85. for row in rows:
  86. print(row)'''
  87. wb = load_workbook(filename = './measurement-temp.xlsx',read_only=False, keep_links=False, data_only=False)
  88. #wb0 = load_workbook(filename = './testfile.xlsx', read_only=False, keep_links=False, data_only=False)
  89. #wb.save(filename = './createfrompy.xlsx');
  90. def findCustomer(code):
  91. global cursor
  92. global env
  93. tempResult = []
  94. views = []
  95. if env == "prod":
  96. views = ["bel_master_view", "e_master_view", "mg_master_view", "v_master_view"]
  97. else:
  98. views = ["bel_master_view_dev", "e_master_view_dev", "mg_master_view_dev", "v_master_view_dev"]
  99. ts = []
  100. select = "distinct MI24 as unbStd, PRO1C as customer, cast(PRO8 as varchar) + ' ' + cast(PRO9 as varchar) + cast(PRO10 as varchar) + 'x' + cast(PRO11 as varchar ) + 'x' + cast(PRO12 as varchar) as sizestring, cast(PRO13 as varchar) + ' ' + cast(PRO14 as varchar) + ' ' + cast(PRO15 as varchar) + ' ' + cast(PRO16 as varchar) + ' ' + cast(PRO17 as varchar) + ' ' + cast(PRO18 as varchar) as spec"
  101. where = "PRO1 = '{0}'".format(code)
  102. for v in views:
  103. sqlQuery = "select {0} from {1} where {2}".format(select, v, where)
  104. ts.append(sqlQuery)
  105. merged = []
  106. for t in ts:
  107. merged += cursor.execute(t)
  108. return merged
  109. def createWS(name, values, codeno, filters):
  110. global wb
  111. #wb.create_sheet(name)
  112. wo = wb['Data Measurement']
  113. ws = wb.copy_worksheet(wo)
  114. ws.title = name
  115. cust = findCustomer(codeno.replace("-", ""))
  116. ws["B2"] = cust[0].customer
  117. applyStyleName(ws["B2"], "blackborder")
  118. ws["B3"] = codeno.replace("-", "")
  119. applyStyleName(ws["B3"], "blackborder")
  120. ws["B4"] = cust[0].sizestring
  121. applyStyleName(ws["B4"], "blackborder")
  122. ws["B5"] = cust[0].spec
  123. applyStyleName(ws["B5"], "blackborder")
  124. bcode = ord('B')
  125. ccode = 2
  126. for idx, val in enumerate(values):
  127. #print(idx)
  128. c = chr(bcode + idx)
  129. #print(val.lot_no)
  130. if ( bcode + idx) > ord('Z'):
  131. r = bcode + idx - ord('Z')
  132. c = 'A' + chr(ord('A') + (r - 1))
  133. #print("c = "+c)
  134. applyStyleName(ws.cell(column= ccode, row=45, value = val.lot_no), "blackborder")
  135. ms = findInMasterView('*', "PRO2 = '{0}'".format(val.lot_no))
  136. #pressInfo = findPressInfo(codeno.replace("-", ""),val.lot_no, filters)
  137. #print("master view")
  138. #print(ms)
  139. if ms:
  140. ws.cell(column = ccode, row=35, value = ms[0].MI24)
  141. #ws[c+'38'] = ms[0].STD_Balance
  142. ws.cell(column = ccode , row=37, value = ms[0].PRO6)
  143. #ws[c+'44'] = ms[0].PRO5
  144. ws.cell(column = ccode, row = 43, value = ms[0].PRO10)
  145. ws.cell(column = ccode, row = 42, value = ms[0].PRO12)
  146. #if pressInfo:
  147. ws.cell(column = ccode , row=39, value = val.Press_UserName)
  148. ws.cell(column = ccode, row = 40, value = val.Press_McName)
  149. #print(type(pressInfo[0].Insp_Date))
  150. #ws[c+'46'].number_format = "Short Date"
  151. ws.cell(column = ccode, row = 46 , value = val.Insp_Date.date())
  152. #print(type(ws[c+'46'].value))
  153. #ws[c+'46'].style = dateStyle
  154. #ws[c+'46'].value = datetime.datetime(2010, 7, 21)
  155. #print(ws[c+'46'].number_format)
  156. #ws[c+'46']. = datetime.datetime
  157. ws.cell(column = ccode , row = 44, value = val.FG_Qty)
  158. dws = updateLength(val.lot_no)
  159. for j,v in enumerate(dws):
  160. ws.cell(column = ccode , row = 48+v.row_no , value = v.weight)
  161. dws = updateUb(val.lot_no)
  162. for j,v in enumerate(dws):
  163. ws.cell(column = ccode , row = 171+v.row_no , value = v.weight)
  164. ccode += 1
  165. c1 = LineChart()
  166. c1.legend.position = "t";
  167. c1.title = "Graph of Result Cp Unbalance"
  168. c1.title.font = Font(underline=Font.UNDERLINE_SINGLE)
  169. c1.y_axis.title = "Unb Weight"
  170. c1.y_axis.number_format = "#,##0.00"
  171. c1.x_axis.title = "Lot No"
  172. c1.width = 30
  173. c1.height = 10
  174. #print(len(values))
  175. lt = Reference(ws, min_col=2, max_col=len(values)+1, min_row=45, max_row=45)
  176. data = Reference(ws, min_col=1, max_col=len(values)+1, min_row=34, max_row=34)
  177. maxUB = Reference(ws, min_col=1, max_col=len(values)+1, min_row=29, max_row=29)
  178. minUB = Reference(ws, min_col=1, max_col=len(values)+1, min_row=30, max_row=30)
  179. avgUB = Reference(ws, min_col=1, max_col=len(values)+1, min_row=31, max_row=31)
  180. vsStd = Reference(ws, min_col=1, max_col=len(values)+1, min_row=36, max_row=36)
  181. c1.add_data(data, from_rows=True, titles_from_data=True)
  182. c1.add_data(minUB, from_rows=True, titles_from_data=True)
  183. c1.add_data(avgUB, from_rows=True, titles_from_data=True)
  184. c1.add_data(vsStd, from_rows=True, titles_from_data=True)
  185. c1.add_data(maxUB, from_rows=True, titles_from_data=True)
  186. s1 = c1.series[0]
  187. s1.marker.symbol = "triangle"
  188. s1.graphicalProperties.line.noFill = True
  189. s1 = c1.series[1]
  190. s1.marker.symbol = "circle"
  191. s1.graphicalProperties.line.noFill = True
  192. s1 = c1.series[2]
  193. s1.marker.symbol = "square"
  194. s1.graphicalProperties.line.noFill = True
  195. s1 = c1.series[4]
  196. s1.marker.symbol = "diamond"
  197. s1.graphicalProperties.line.noFill = True
  198. c1.set_categories(lt)
  199. c1.x_axis.txPr = RichText(bodyPr=RichTextProperties(anchor="ctr",anchorCtr="1",rot="-2700000",
  200. spcFirstLastPara="1",vertOverflow="ellipsis",wrap="square"),
  201. p=[Paragraph(pPr=ParagraphProperties(defRPr=CharacterProperties()), endParaRPr=CharacterProperties())])
  202. ws.add_chart(c1, "A7")
  203. #newws.title = name
  204. #copy data cp ws
  205. #insert values in the sheet
  206. def findInMasterView(select, where):
  207. global cursor
  208. global env
  209. tempResult = []
  210. views = []
  211. if env == "prod":
  212. views = ["bel_master_view", "e_master_view", "mg_master_view", "v_master_view"]
  213. else:
  214. views = ["bel_master_view_dev", "e_master_view_dev", "mg_master_view_dev", "v_master_view_dev"]
  215. ts = []
  216. for v in views:
  217. sqlQuery = "select {0} from {1} where {2}".format(select, v, where)
  218. ts.append(sqlQuery);
  219. qj = ';'.join(ts)
  220. #print(qj)
  221. merged = []
  222. for t in ts:
  223. merged += cursor.execute(t)
  224. if len(merged) > 0:
  225. return merged
  226. return merged
  227. def findPressInfo(code, lot, year):
  228. global cursor
  229. global env
  230. fyear = year.replace("created_at", "Insp_Date")
  231. q = "select * from tb_fg_pressinfo_lotlist where ProductCode = '{0}' and LotNo = '{1}' and {2}" \
  232. .format(code, lot, fyear)
  233. cursor.execute(q)
  234. return cursor.fetchall()
  235. def findProductDimension(codeno):
  236. stdSizes = """
  237. select * from AllProduct_Dimension_ForInsProcess where ProductCode='{0}'""".format(codeno.replace("-", ""))
  238. #print(stdSizes)
  239. return stdSizes
  240. def generateSQLDataMS(codeno, filters):
  241. if codeno.find('-') != -1:
  242. codeString = codeno
  243. else:
  244. codeString = codeno[0] + "-" + codeno[1:5] + "-" + codeno[5:9] + "-" + codeno[9:10]
  245. if filters is not None:
  246. qMsData = """
  247. select * from data_ms where code='{0}' and {1} order by lot_no asc, row_no asc
  248. """.format(codeString, filters)
  249. else:
  250. qMsData = """
  251. select * from data_ms where code='{0}' order by lot_no asc, row_no asc
  252. """.format(codeString)
  253. return qMsData
  254. def updateLength(lotno):
  255. global cursor
  256. global wb
  257. q = "select * from data_wb where lot_no = '{0}' and judgement='OK' order by row_no asc".format(lotno)
  258. #print(q);
  259. return cursor.execute(q)
  260. def updateUb(lotno):
  261. global cursor
  262. global wb
  263. q = "select * from data_wb where lot_no = '{0}' and judgement='NG' order by row_no asc".format(lotno)
  264. #print(q);
  265. return cursor.execute(q)
  266. def actualChart(ws, title, data, position_data, body_data, cat_pos, position):
  267. '''
  268. for row in rows:
  269. ws.append(row)
  270. '''
  271. if isinstance(position_data, str):
  272. rs = ws[position_data]
  273. else:
  274. rs = tuple(ws.iter_rows(**position_data))
  275. for i in range(len(rs)):
  276. for j in range(len(rs[i])):
  277. print(rs[i][j])
  278. rs[i][j].value = data[i][j]
  279. #ws["A1"].value = rows
  280. #print(cells)
  281. #print(rs)
  282. #return
  283. c1 = LineChart()
  284. c1.width = 10
  285. #c1.height = 10
  286. c1.title = title
  287. c1.style = 13
  288. c1.y_axis.title = 'Size'
  289. c1.x_axis.title = 'Lot'
  290. #print(ws.title+"?"+position_data)
  291. if isinstance(body_data, str):
  292. rdata = Reference(range_string=ws.title+"!"+body_data)
  293. else:
  294. rdata = Reference(ws, **body_data)
  295. c1.add_data(rdata, titles_from_data=True)
  296. if isinstance(cat_pos, str):
  297. lots = Reference(range_string=ws.title+"!"+cat_pos)
  298. else:
  299. lots = Reference(ws, **cat_pos)
  300. c1.set_categories(lots)
  301. # Style the lines
  302. s1 = c1.series[0]
  303. s1.marker.symbol = "triangle"
  304. s1.marker.graphicalProperties.solidFill = "FF0000" # Marker filling
  305. s1.marker.graphicalProperties.line.solidFill = "FF0000" # Marker outline
  306. s1.graphicalProperties.line.noFill = True
  307. s2 = c1.series[1]
  308. s2.graphicalProperties.line.solidFill = "00AAAA"
  309. s2.graphicalProperties.line.dashStyle = "sysDot"
  310. s2.graphicalProperties.line.width = 100050 # width in EMUs
  311. s2 = c1.series[2]
  312. s2.smooth = True # Make the line smooth
  313. if isinstance(position,str):
  314. ws.add_chart(c1, position)
  315. else:
  316. ptemp = get_column_letter(position[1])
  317. #print("ptemp = ", ptemp)
  318. ws.add_chart(c1, ptemp + str(position[0]))
  319. def createXBarChart(codeno, filters):
  320. global cursor
  321. global wb
  322. global dateStyle
  323. global codeMap
  324. ws = wb.create_sheet("X Bar,R Chart", 3)
  325. #find lot in a codeno
  326. sql = generateSQLDataMS(codeno, filters)
  327. sql2 = findProductDimension(codeno)
  328. cursor.execute(sql)
  329. row = cursor.fetchall()
  330. cursor.execute(sql2)
  331. row2 = cursor.fetchall()
  332. temp = {}
  333. #map data into lotno list
  334. #find max, min
  335. sizes = {}
  336. stdSizes = {}
  337. num = 0
  338. for k in row2:
  339. if k.Size_Id in codeMap:
  340. sn = codeMap[k.Size_Id].lower()+"size"
  341. sizes[sn] = []
  342. stdSizes[sn] = k
  343. for r in row:
  344. #print(r)
  345. if r.lot_no not in temp:
  346. temp[r.lot_no] = []
  347. temp[r.lot_no].append(r)
  348. for k,v in sizes.items():
  349. sizes[k].append(getattr(r, k, None))
  350. #print("temp = ", temp)
  351. #print("temp keys = ", temp.keys());
  352. for k,v in temp.items():
  353. #print("k = ", k)
  354. num = len(v)
  355. #break
  356. #print("num = ", num)
  357. if num > 5:
  358. num = 5
  359. #filter only dimensions in master
  360. #print("TEMP == \n")
  361. #print(sizes)
  362. avgSize = {}
  363. minSize = {}
  364. maxSize = {}
  365. data2 = []
  366. data2.append(["Lot No"])
  367. for k,v in temp.items():
  368. data2[0].append(k)
  369. #print("data 2 = ", data2)
  370. #create maxtrix in form
  371. '''
  372. Lot, 1, 2, 3, 4, 5, max, min
  373. xxx, v, v, v, v, v, v, v
  374. '''
  375. bp = 1
  376. for keySize, keyValue in sizes.items():
  377. l = []
  378. n0 = 0
  379. beginRow = 2
  380. #print("key size = %s\n" %(keySize) )
  381. for k,v in temp.items():
  382. a0 = []
  383. a0.append(k)
  384. sv = len(v)
  385. if sv > 5:
  386. sv = 5
  387. n0 = sv
  388. for i in range(sv):
  389. a0.append(getattr(v[i], keySize, 0))
  390. avg = sum(a0[1:]) / len(a0[1:])
  391. a0.append(avg)
  392. r = max(a0[1:]) - min(a0[1:])
  393. a0.append(r)
  394. #print("std size ", stdSizes[keySize])
  395. maxMaster = float(stdSizes[keySize].Std) + float(stdSizes[keySize].TolUp)
  396. minMaster = float(stdSizes[keySize].Std) + float(stdSizes[keySize].TolUn)
  397. a0.append(maxMaster)
  398. a0.append(minMaster)
  399. l.append(a0)
  400. #print("l = ", l)
  401. header = ["Lot No"] + [str(i+1) for i in range(n0)] + ["avg", "r", "max", "min"]
  402. #print("header =", header)
  403. l = [header] + l;
  404. #print("l = ", l)
  405. '''
  406. tranpose above matrix into form:
  407. Lot,xxx, xxx, xxx,
  408. 1, v, v, v
  409. 2, v, v, v
  410. ...
  411. '''
  412. m, n = len(l), len(l[0])
  413. #print("mxn = ", m, n)
  414. ta = [ [0 for j in range(m)] for i in range(n)]
  415. #print("ta = ", ta)
  416. for i in range(len(l)):
  417. for j in range(len(l[i])):
  418. try:
  419. ta[j][i] = l[i][j]
  420. except:
  421. pass
  422. #print("TA ", ta)
  423. #print(len(ta), len(ta[0]))
  424. #print("===\n")
  425. #print(beginRow, beginRow + len(ta) - 1, bp, (bp-1) + len(ta[0]))
  426. wsRows = tuple(ws.iter_rows(min_row=beginRow, max_row=beginRow + len(ta) - 1, min_col=bp, max_col=(bp-1)+len(ta[0])))
  427. for i in range(len(wsRows)):
  428. for j in range(len(wsRows[i])):
  429. #print(i,j)
  430. wsRows[i][j].value = ta[i][j]
  431. wsRows[i][j].number_format = '0.00'
  432. bd = Side(style='medium', color="000000")
  433. wsRows[i][j].border = Border(left=bd, top=bd, right=bd, bottom=bd)
  434. ws.cell(1, bp, value = "%s-size (bar)" % (keySize.upper().replace("SIZE", "")))
  435. #bp += len(ta[0]) + 2
  436. #continue
  437. cpos = utils.get_column_letter(bp) + "15"
  438. font_test = drawingText.Font(typeface='Calibri')
  439. cp = CharacterProperties(latin=font_test, sz=1000)
  440. c1 = LineChart()
  441. pp = ParagraphProperties(defRPr=cp)
  442. cp1 = CharacterProperties(latin=font_test, sz=1400)
  443. pp1 = ParagraphProperties(defRPr=cp1)
  444. minValues = Reference(ws, min_row=beginRow+9, min_col=bp+1, max_row=beginRow+9, max_col=(bp-1)+len(ta[0]) )
  445. minSerie = Series(minValues, title="Min")
  446. c1.append(minSerie)
  447. maxValues = Reference(ws, min_row=beginRow+8, min_col=bp+1, max_row=beginRow+8, max_col=(bp-1)+len(ta[0]) )
  448. maxSerie = Series(maxValues, title="Max")
  449. c1.append(maxSerie)
  450. avgValues = Reference(ws, min_row=beginRow+6, min_col=bp+1, max_row=beginRow+6, max_col=(bp-1)+len(ta[0]) )
  451. avgSerie = Series(avgValues, title="Avg")
  452. avgSerie.marker.symbol = "circle"
  453. avgSerie.marker.graphicalProperties.solidFill = "4f81bd" # Marker filling
  454. avgSerie.graphicalProperties.line.solidFill = "4f81bd"
  455. c1.append(avgSerie)
  456. lots = Reference(ws,min_row=beginRow, min_col=bp+1, max_row=beginRow, max_col=(bp-1)+len(ta[0]))
  457. c1.set_categories(lots)
  458. c1.width = len(ta[0])*2.7
  459. c1.title = "%s-size (X bar)" % (keySize.upper().replace("SIZE", ""))
  460. #c1.title.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)])
  461. c1.y_axis.title = "Value(mm.)"
  462. c1.x_axis.title = "Lot No."
  463. c1.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  464. c1.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  465. c1.title.tx.rich.p[0].pPr = pp1# Works!
  466. c1.legend.position = "b"
  467. ws.add_chart(c1, cpos)
  468. cpos = utils.get_column_letter(bp) + "30"
  469. c2 = LineChart()
  470. #c2.title.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)])
  471. rValues = Reference(ws, min_row=beginRow+7, min_col=bp+1, max_row=beginRow+7, max_col=(bp-1)+len(ta[0]) )
  472. rSerie = Series(rValues, title="R")
  473. c2.append(rSerie)
  474. lots = Reference(ws,min_row=beginRow, min_col=bp+1, max_row=beginRow, max_col=(bp-1)+len(ta[0]))
  475. c2.set_categories(lots)
  476. c2.width = len(ta[0])*2.7
  477. c2.title = "%s-size (R)" % (keySize.upper().replace("SIZE", ""))
  478. c2.y_axis.title = "Value(mm.)"
  479. c2.x_axis.title = "Lot No."
  480. c2.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  481. c2.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  482. c2.title.tx.rich.p[0].pPr = pp1# Works!
  483. c2.legend.position = "b"
  484. ws.add_chart(c2, cpos)
  485. #move column cursor
  486. bp += len(ta[0]) + 5
  487. def createCp(codeno, filters):
  488. global cursor
  489. global wb
  490. global dateStyle
  491. global codeMap
  492. ws = wb.create_sheet("CP Press")
  493. #find lot in a codeno
  494. sql = generateSQLDataMS(codeno, filters)
  495. sql2 = findProductDimension(codeno)
  496. cursor.execute(sql)
  497. row = cursor.fetchall()
  498. cursor.execute(sql2)
  499. row2 = cursor.fetchall()
  500. temp = {}
  501. #map data into lotno list
  502. #find max, min
  503. sizes = {}
  504. stdSizes = {}
  505. for k in row2:
  506. if k.Size_Id in codeMap:
  507. sn = codeMap[k.Size_Id].lower()+"size"
  508. sizes[sn] = []
  509. stdSizes[sn] = k
  510. for r in row:
  511. #print(r)
  512. if r.lot_no not in temp:
  513. temp[r.lot_no] = []
  514. temp[r.lot_no].append(r)
  515. for k,v in sizes.items():
  516. sizes[k].append(getattr(r, k, None))
  517. #print("temp = ", temp)
  518. #print("temp keys = ", temp.keys());
  519. for k,v in temp.items():
  520. #print("k = ", k)
  521. num = len(v)
  522. #break
  523. #print("num = ", num)
  524. if num > 5:
  525. num = 5
  526. #filter only dimensions in master
  527. #print("TEMP == \n")
  528. #print(sizes)
  529. avgSize = {}
  530. minSize = {}
  531. maxSize = {}
  532. data2 = []
  533. data2.append(["Lot No"])
  534. for k,v in temp.items():
  535. data2[0].append(k)
  536. #print("data 2 = ", data2)
  537. #create maxtrix in form
  538. '''
  539. Lot, 1, 2, 3, 4, 5, max, min
  540. xxx, v, v, v, v, v, v, v
  541. '''
  542. bp = 1
  543. for keySize, keyValue in sizes.items():
  544. l = []
  545. n0 = 0
  546. beginRow = 2
  547. #print("key size = %s\n" %(keySize) )
  548. for k,v in temp.items():
  549. a0 = []
  550. a0.append(k)
  551. sv = len(v)
  552. if sv > 5:
  553. sv = 5
  554. n0 = sv
  555. for i in range(sv):
  556. a0.append(getattr(v[i], keySize, 0))
  557. avg = sum(a0[1:]) / len(a0[1:])
  558. a0.append(avg)
  559. r = max(a0[1:]) - min(a0[1:])
  560. a0.append(r)
  561. #print("std size ", stdSizes[keySize])
  562. maxMaster = float(stdSizes[keySize].Std) + float(stdSizes[keySize].TolUp)
  563. minMaster = float(stdSizes[keySize].Std) + float(stdSizes[keySize].TolUn)
  564. a0.append(maxMaster)
  565. a0.append(minMaster)
  566. l.append(a0)
  567. #print("l = ", l)
  568. header = ["Lot No"] + [str(i+1) for i in range(n0)] + ["avg", "r", "max", "min"]
  569. #print("header =", header)
  570. l = [header] + l;
  571. #print("l = ", l)
  572. '''
  573. tranpose above matrix into form:
  574. Lot,xxx, xxx, xxx,
  575. 1, v, v, v
  576. 2, v, v, v
  577. ...
  578. '''
  579. m, n = len(l), len(l[0])
  580. #print("mxn = ", m, n)
  581. ta = [ [0 for j in range(m)] for i in range(n)]
  582. #print("ta = ", ta)
  583. for i in range(len(l)):
  584. for j in range(len(l[i])):
  585. ta[j][i] = l[i][j]
  586. #print("TA ", ta)
  587. #print(len(ta), len(ta[0]))
  588. #print("===\n")
  589. #print(beginRow, beginRow + len(ta) - 1, bp, (bp-1) + len(ta[0]))
  590. wsRows = tuple(ws.iter_rows(min_row=beginRow, max_row=beginRow + len(ta) - 1, min_col=bp, max_col=(bp-1)+len(ta[0])))
  591. for i in range(len(wsRows)):
  592. for j in range(len(wsRows[i])):
  593. #print(i,j)
  594. wsRows[i][j].value = ta[i][j]
  595. wsRows[i][j].number_format = '0.00'
  596. bd = Side(style='medium', color="000000")
  597. wsRows[i][j].border = Border(left=bd, top=bd, right=bd, bottom=bd)
  598. ws.cell(1, bp, value = "%s-size (bar)" % (keySize.upper().replace("SIZE", "")))
  599. #bp += len(ta[0]) + 2
  600. #continue
  601. cpos = utils.get_column_letter(bp) + "15"
  602. font_test = drawingText.Font(typeface='Calibri')
  603. cp = CharacterProperties(latin=font_test, sz=1000)
  604. c1 = LineChart()
  605. pp = ParagraphProperties(defRPr=cp)
  606. cp1 = CharacterProperties(latin=font_test, sz=1400)
  607. pp1 = ParagraphProperties(defRPr=cp1)
  608. minValues = Reference(ws, min_row=beginRow+9, min_col=bp+1, max_row=beginRow+9, max_col=(bp-1)+len(ta[0]) )
  609. minSerie = Series(minValues, title="Min")
  610. c1.append(minSerie)
  611. maxValues = Reference(ws, min_row=beginRow+8, min_col=bp+1, max_row=beginRow+8, max_col=(bp-1)+len(ta[0]) )
  612. maxSerie = Series(maxValues, title="Max")
  613. c1.append(maxSerie)
  614. avgValues = Reference(ws, min_row=beginRow+6, min_col=bp+1, max_row=beginRow+6, max_col=(bp-1)+len(ta[0]) )
  615. avgSerie = Series(avgValues, title="Avg")
  616. avgSerie.marker.symbol = "circle"
  617. avgSerie.marker.graphicalProperties.solidFill = "4f81bd" # Marker filling
  618. avgSerie.graphicalProperties.line.solidFill = "4f81bd"
  619. c1.append(avgSerie)
  620. lots = Reference(ws,min_row=beginRow, min_col=bp+1, max_row=beginRow, max_col=(bp-1)+len(ta[0]))
  621. c1.set_categories(lots)
  622. c1.width = len(ta[0])*3.5
  623. c1.title = "%s-size (X bar)" % (keySize.upper().replace("SIZE", ""))
  624. #c1.title.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)])
  625. c1.y_axis.title = "Value(mm.)"
  626. c1.x_axis.title = "Lot No."
  627. c1.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  628. c1.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  629. c1.title.tx.rich.p[0].pPr = pp1# Works!
  630. c1.legend.position = "b"
  631. ws.add_chart(c1, cpos)
  632. cpos = utils.get_column_letter(bp) + "30"
  633. c2 = LineChart()
  634. #c2.title.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)])
  635. rValues = Reference(ws, min_row=beginRow+7, min_col=bp+1, max_row=beginRow+7, max_col=(bp-1)+len(ta[0]) )
  636. rSerie = Series(rValues, title="R")
  637. c2.append(rSerie)
  638. lots = Reference(ws,min_row=beginRow, min_col=bp+1, max_row=beginRow, max_col=(bp-1)+len(ta[0]))
  639. c2.set_categories(lots)
  640. c2.width = len(ta[0])*3.5
  641. c2.title = "%s-size (R)" % (keySize.upper().replace("SIZE", ""))
  642. c2.y_axis.title = "Value(mm.)"
  643. c2.x_axis.title = "Lot No."
  644. c2.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  645. c2.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  646. c2.title.tx.rich.p[0].pPr = pp1# Works!
  647. c2.legend.position = "b"
  648. ws.add_chart(c2, cpos)
  649. #move column cursor
  650. bp += len(ta[0]) + 5
  651. #create each size table and chart types
  652. # actual chart
  653. def createChart(codeno, filters):
  654. global cursor
  655. global wb
  656. global dateStyle
  657. global codeMap
  658. #ws = wb.create_sheet("chart2")
  659. #find lot in a codeno
  660. sql = generateSQLDataMS(codeno, filters)
  661. #print(sql)
  662. sql2 = findProductDimension(codeno)
  663. cursor.execute(sql)
  664. row = cursor.fetchall()
  665. cursor.execute(sql2)
  666. row2 = cursor.fetchall()
  667. temp = {}
  668. #map data into lotno list
  669. #find max, min
  670. sizes = {}
  671. stdSizes = {}
  672. for k in row2:
  673. if k.Size_Id in codeMap:
  674. sn = codeMap[k.Size_Id].lower()+"size"
  675. sizes[sn] = []
  676. stdSizes[sn] = k
  677. for r in row:
  678. #print(r)
  679. if r.lot_no not in temp:
  680. temp[r.lot_no] = []
  681. temp[r.lot_no].append(r)
  682. for k,v in sizes.items():
  683. sizes[k].append(getattr(r, k, None))
  684. #filter only dimensions in master
  685. #print("TEMP == \n")
  686. #print(sizes)
  687. avgSize = {}
  688. minSize = {}
  689. maxSize = {}
  690. for k, v in sizes.items():
  691. #print(k, v)
  692. if len(v) > 0 and v[0] is not None:
  693. avgSize[k] = sum(v)/len(v)
  694. minSize[k] = min(v)
  695. maxSize[k] = max(v)
  696. #print("avg size \n",avgSize)
  697. #print("min size \n",minSize)
  698. #print("max size \n",maxSize)
  699. for k1,v1 in temp.items():
  700. #print("\nlot %s \n" %( k1))
  701. ws = wb.create_sheet("lot %s actual" %(k1))
  702. i = 0
  703. bp = 1
  704. for k,v in sizes.items():
  705. #print("%s actual" % (k))
  706. data = [
  707. ["Max (%s) size" % (k) ],
  708. ['Min'],
  709. ['Actual'],
  710. ['No.'],
  711. ['Lot No.']
  712. ]
  713. nrow = len(data)
  714. for v2 in v1:
  715. #print("std size ", stdSizes[keySize])
  716. maxMaster = float(stdSizes[k].Std) + float(stdSizes[k].TolUp)
  717. minMaster = float(stdSizes[k].Std) + float(stdSizes[k].TolUn)
  718. data[0].append(maxMaster)
  719. data[1].append(minMaster)
  720. data[2].append(getattr(v2, k))
  721. data[3].append(v2.row_no)
  722. data[4].append(v2.lot_no)
  723. #print(data)
  724. #gen chart
  725. #print("min col ", bp)
  726. wsRows = tuple(ws.iter_rows(min_row=1, max_row=len(data), min_col=bp, max_col= (bp - 1)+len(data[0])))
  727. for i in range(len(wsRows)):
  728. for j in range(len(wsRows[i])):
  729. #print(i,j)
  730. #data[i][j])
  731. #print(wsRows[i][j])
  732. wsRows[i][j].value = data[i][j]
  733. if i != 3:
  734. wsRows[i][j].number_format = '0.00'
  735. bd = Side(style='medium', color="000000")
  736. wsRows[i][j].border = Border(left=bd, top=bd, right=bd, bottom=bd)
  737. cpos = utils.get_column_letter(bp) + "10"
  738. font_test = drawingText.Font(typeface='Calibri')
  739. cp = CharacterProperties(latin=font_test, sz=1000)
  740. pp = ParagraphProperties(defRPr=cp)
  741. cp1 = CharacterProperties(latin=font_test, sz=1400)
  742. pp1 = ParagraphProperties(defRPr=cp1)
  743. c1 = LineChart()
  744. maxValues = Reference(ws, min_row=1, min_col=bp+1, max_row=1, max_col=(bp-1)+len(data[0]) )
  745. maxSerie = Series(maxValues, title="Max")
  746. maxSerie.graphicalProperties.line.solidFill = "FF0000"
  747. c1.append(maxSerie)
  748. minValues = Reference(ws, min_row=2, min_col=bp+1, max_row=2, max_col=(bp-1)+len(data[0]) )
  749. minSerie = Series(minValues, title="Min")
  750. minSerie.graphicalProperties.line.solidFill = "000000"
  751. c1.append(minSerie)
  752. acValues = Reference(ws, min_row=3, min_col=bp+1, max_row=3, max_col=(bp-1)+len(data[0]) )
  753. acSerie = Series(acValues, title="Actual")
  754. acSerie.marker.graphicalProperties.solidFill = "4f81bd" # Marker filling
  755. acSerie.graphicalProperties.line.solidFill = "4f81bd"
  756. acSerie.marker.symbol = "circle"
  757. c1.append(acSerie)
  758. lots = Reference(ws,min_row=4, min_col=bp+1, max_row=4, max_col=(bp-1)+len(data[0]))
  759. c1.set_categories(lots)
  760. c1.width = len(data[0])*1.8
  761. c1.title = "%s-size (actual) " % (k.upper().replace("SIZE", ""))
  762. c1.y_axis.title = "Value(mm.)"
  763. c1.x_axis.title = "Item No."
  764. c1.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  765. c1.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  766. c1.title.tx.rich.p[0].pPr = pp1# Works!
  767. c1.legend.position = "b"
  768. ws.add_chart(c1, cpos)
  769. bp += len(data[0]) + 2
  770. #print()
  771. #print("M"+str(bp))
  772. #bp += coEndCell[1]+1+10
  773. #print(ws.calculate_dimension())
  774. #create each size table and chart types
  775. # actual chart
  776. def createExcel(codeno, filters):
  777. global cursor
  778. global wb
  779. global dateStyle
  780. global stdSizeMapColumn
  781. ws = wb["Data Measurement"]
  782. codeString = ""
  783. if codeno.find('-') != -1:
  784. codeString = codeno
  785. else:
  786. codeString = codeno[0] + "-" + codeno[1:5] + "-" + codeno[5:9] + "-" + codeno[9:10]
  787. # std sizes
  788. stdSizes = """
  789. select * from AllProduct_Dimension_ForInsProcess where ProductCode='{0}'""".format(codeString.replace("-", ""))
  790. #print(stdSizes)
  791. cursor.execute(stdSizes)
  792. rows = cursor.fetchall()
  793. for k,v in stdSizeMapColumn.items():
  794. if k not in ["Weight", "Result"]:
  795. ws.column_dimensions[v].hidden = True
  796. enableCols = []
  797. for r in rows:
  798. minv = float(r.Std) + float(r.TolUn)
  799. stdv = float(r.Std)
  800. maxv = float(r.Std) + float(r.TolUp)
  801. #print(r.Size_Name.replace("size", "").replace("Size", "").strip())
  802. #print(r.Size_Name.replace("size", "").replace("Size", "").strip() in stdSizeMapColumn)
  803. if r.Size_Name.replace("size", "").replace("Size", "").strip() in stdSizeMapColumn:
  804. colName = stdSizeMapColumn[r.Size_Name.replace("size", "").replace("Size", "").strip()]
  805. #print(colName)
  806. #print(colName+"12")
  807. #print(min)
  808. ws.column_dimensions[colName].hidden = False
  809. ws.column_dimensions[colName].bestFit = True
  810. ws.column_dimensions[colName].width = 8
  811. #print(colName)
  812. #print(ws.column_dimensions[colName].hidden)
  813. #print(ws.column_dimensions[colName].collapsed)
  814. #print(ws.column_dimensions[colName].bestFit)
  815. #print(ws.column_dimensions[colName].width)
  816. ws[colName+"12"] = minv #min
  817. applyStyleName(ws[colName+"12"], "border", "0.00")
  818. ws[colName+"11"] = stdv #std
  819. applyStyleName(ws[colName+"11"], "border", "0.00")
  820. ws[colName+"10"] = maxv #max
  821. applyStyleName(ws[colName+"10"], "border", "0.00")
  822. enableCols.append(r.Size_Name.replace("size", "").replace("Size", "").strip())
  823. #print(enableCols)
  824. maxQuery = [ "max(%ssize) as %s"% ( x.lower(), x.upper() ) for x in enableCols]
  825. #print(maxQuery)
  826. if filters is not None:
  827. if codeno != "undefined":
  828. qt = "select {2} from data_ms where code='{0}' and ( (size1 > 0) or (size2 > 0)) and {1}".format(codeString, filters, ",".join(maxQuery))
  829. else:
  830. qt = "select * from data_ms where ( (size1 > 0) or (size2 > 0)) and {1}".format(codeString, filters, ",".join(maxQuery))
  831. else:
  832. if codeno != "undefined":
  833. qt = "select {1} from data_ms where code='{0}' and ( (size1 > 0 ) or (size2 > 0))".format(codeString, ",".join(maxQuery))
  834. else:
  835. qt = "select * from data_ms where ( (size1 > 0) or (size2 > 0))".format(codeString, ",".join(maxQuery))
  836. #print("qt = ", qt)
  837. cursor.execute(qt)
  838. rows = cursor.fetchall()
  839. for r in rows:
  840. #print(r.cursor_description)
  841. for c in r.cursor_description:
  842. #print(c)
  843. #print(getattr(r, c[0]))
  844. colName = stdSizeMapColumn[c[0]]
  845. ws[colName+"8"] = getattr(r, c[0])
  846. applyStyleName(ws[colName+"8"], "border")
  847. maxQuery = [ "min(%ssize) as %s"% ( x.lower(), x.upper() ) for x in enableCols]
  848. #print(maxQuery)
  849. if filters is not None:
  850. if codeno != "undefined":
  851. qt = "select {2} from data_ms where code='{0}' and {1}".format(codeString, filters, ",".join(maxQuery))
  852. else:
  853. qt = "select * from data_ms where {1}".format(codeString, filters, ",".join(maxQuery))
  854. else:
  855. if codeno != "undefined":
  856. qt = "select {1} from data_ms where code='{0}'".format(codeString, ",".join(maxQuery))
  857. else:
  858. qt = "select * from data_ms".format(codeString, ",".join(maxQuery))
  859. '''
  860. if filters is not None:
  861. qt = "select {2} from data_ms where code='{0}' and {1}".format(codeString, filters, ",".join(maxQuery))
  862. else:
  863. qt = "select {1} from data_ms where code='{0}'".format(codeString, ",".join(maxQuery))
  864. '''
  865. #print(qt)
  866. cursor.execute(qt)
  867. rows = cursor.fetchall()
  868. for r in rows:
  869. #print(r.cursor_description)
  870. for c in r.cursor_description:
  871. #print(c)
  872. #print(getattr(r, c[0]))
  873. colName = stdSizeMapColumn[c[0]]
  874. ws[colName+"9"] = getattr(r, c[0])
  875. applyStyleName(ws[colName+"9"], "border")
  876. #query data
  877. if filters is not None:
  878. qMsData = """
  879. select * from data_ms where code='{0}' and {1} order by lot_no asc, row_no asc
  880. """.format(codeString, filters)
  881. else:
  882. qMsData = """
  883. select * from data_ms where code='{0}' order by lot_no asc, row_no asc
  884. """.format(codeString)
  885. cursor.execute(qMsData)
  886. rows = cursor.fetchall()
  887. startRow = 15
  888. for r in rows:
  889. isNG = False
  890. if r.dsize == 0 and r.hsize == 0 and r.tsize == 0:
  891. continue
  892. if int(r.row_no) == 1:
  893. ws.cell(column = 1, row = startRow, value = r.created_at).number_format = "m/d/yy"
  894. applyStyleName(ws.cell(column = 1, row = startRow), "border", "m/d/yy")
  895. ws.cell(column = 2, row = startRow, value = r.code)
  896. applyStyleName(ws.cell(column = 2, row = startRow), "border")
  897. ws.cell(column = 3, row = startRow, value=r.lot_no)
  898. applyStyleName(ws.cell(column = 3, row = startRow), "border")
  899. countLot = """
  900. select count(*) as c from data_ms where lot_no = '{0}'
  901. """.format(r.lot_no)
  902. cursor.execute(countLot)
  903. countResult = cursor.fetchall()
  904. #print(countResult)
  905. ws.cell(column = 4, row = startRow, value = countResult[0].c).number_format = "0"
  906. applyStyleName(ws.cell(column = 4, row = startRow), "border")
  907. c = ws.cell(column=5, row = startRow, value = int(r.row_no))
  908. applyStyleName(ws.cell(column = 5, row = startRow), "border")
  909. c.number_format = "0"
  910. colstr = stdSizeMapColumn.get("D")
  911. ws[colstr + str(startRow)] = r.dsize
  912. applyStyleName(ws[colstr + str(startRow)], "border")
  913. if r.dsizeOk == "NG":
  914. isNG = True
  915. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  916. colstr = stdSizeMapColumn.get("T")
  917. ws[colstr + str(startRow)] = r.tsize
  918. applyStyleName(ws[colstr + str(startRow)], "border")
  919. if r.tsizeOk == "NG":
  920. isNG = True
  921. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  922. colstr = stdSizeMapColumn.get("H")
  923. applyStyleName(ws[colstr + str(startRow)], "border")
  924. if ( r.hdev is not None) and ( r.hsizeproxy is not None ) and (r.hsizeproxy != 'null') and ( r.hdev.strip() != "") and (r.hdev.strip() != 'null'):
  925. ws[colstr + str(startRow)] = "%s/%s" % (r.hsizeproxy.strip(), r.hdev.strip())
  926. else:
  927. if ( r.hsizeproxy is not None ) and ( r.hsizeproxy.strip() != 'null'):
  928. proxyStrip = r.hsizeproxy.strip()
  929. if proxyStrip == "OK" or proxyStrip == "NG":
  930. ws[colstr + str(startRow)] = proxyStrip
  931. else:
  932. try:
  933. ws[colstr + str(startRow)] = float(proxyStrip.replace("+", ""))
  934. except Exception as e:
  935. pass
  936. if r.hsizeOk == "NG":
  937. isNG = True
  938. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  939. colstr = stdSizeMapColumn.get("C")
  940. ws[colstr + str(startRow)] = r.csize
  941. applyStyleName(ws[colstr + str(startRow)], "border")
  942. if r.csizeOk == "NG":
  943. isNG = True
  944. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  945. colstr = stdSizeMapColumn.get("E")
  946. ws[colstr + str(startRow)] = r.esize
  947. applyStyleName(ws[colstr + str(startRow)], "border")
  948. if r.esizeOk == "NG":
  949. isNG = True
  950. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  951. colstr = stdSizeMapColumn.get("F")
  952. ws[colstr + str(startRow)] = r.fsize
  953. applyStyleName(ws[colstr + str(startRow)], "border")
  954. if r.fsizeOk == "NG":
  955. isNG = True
  956. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  957. colstr = stdSizeMapColumn.get("G")
  958. ws[colstr + str(startRow)] = r.gsize
  959. applyStyleName(ws[colstr + str(startRow)], "border")
  960. if r.gsizeOk == "NG":
  961. isNG = True
  962. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  963. colstr = stdSizeMapColumn.get("J")
  964. ws[colstr+str(startRow)] = r.jsize
  965. applyStyleName(ws[colstr + str(startRow)], "border")
  966. if r.jsizeOk == "NG":
  967. isNG = True
  968. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  969. colstr = stdSizeMapColumn.get("K")
  970. ws[colstr+str(startRow)] = r.ksize
  971. applyStyleName(ws[colstr + str(startRow)], "border")
  972. if r.ksizeOk == "NG":
  973. isNG = True
  974. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  975. colstr = stdSizeMapColumn.get("M")
  976. ws[colstr+str(startRow)] = r.msize
  977. applyStyleName(ws[colstr + str(startRow)], "border")
  978. if r.msizeOk == "NG":
  979. isNG = True
  980. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  981. colstr = stdSizeMapColumn.get("N")
  982. ws[colstr+str(startRow)] = r.nsize
  983. applyStyleName(ws[colstr + str(startRow)], "border")
  984. if r.nsizeOk == "NG":
  985. isNG = True
  986. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  987. colstr = stdSizeMapColumn.get("P")
  988. ws[colstr+str(startRow)] = r.psize
  989. applyStyleName(ws[colstr + str(startRow)], "border")
  990. if r.psizeOk == "NG":
  991. isNG = True
  992. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  993. colstr = stdSizeMapColumn.get("U")
  994. ws[colstr+str(startRow)] = r.usize
  995. applyStyleName(ws[colstr + str(startRow)], "border")
  996. if r.usizeOk == "NG":
  997. isNG = True
  998. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  999. colstr = stdSizeMapColumn.get("W")
  1000. ws[colstr+str(startRow)] = r.wsize
  1001. applyStyleName(ws[colstr + str(startRow)], "border")
  1002. if r.wsizeOk == "NG":
  1003. isNG = True
  1004. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1005. colstr = stdSizeMapColumn.get("Weight")
  1006. ws[colstr+str(startRow)] = r.weight
  1007. applyStyleName(ws[colstr + str(startRow)], "border")
  1008. colstr = stdSizeMapColumn.get("Result")
  1009. applyStyleName(ws[colstr + str(startRow)], "border")
  1010. if isNG == True:
  1011. ws[colstr+ str(startRow)] = "NG"
  1012. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1013. else:
  1014. ws[colstr+ str(startRow)] = "OK"
  1015. '''
  1016. colstr = stdSizeMapColumn.get("X")
  1017. ws[colstr+str(startRow)].value = r.xsize
  1018. if r.xsizeOk == "NG":
  1019. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1020. '''
  1021. #ws['U'+str(startRow)] = r.ysize or 0
  1022. #ysize.font= Font(color = colors.Red)
  1023. #ws['V'+str(startRow)] = r.zsize
  1024. startRow += 1
  1025. #print(ws._charts)
  1026. if codeno != "undefined":
  1027. cust = findCustomer(codeno.replace("-", ""))
  1028. ws["B3"] = codeno.replace("-", "")
  1029. applyStyleName(ws["B3"], "border")
  1030. if cust:
  1031. ws["B2"] = cust[0].customer
  1032. applyStyleName(ws["B2"], "border")
  1033. ws["B4"] = cust[0].sizestring
  1034. applyStyleName(ws["B4"], "border")
  1035. ws["B5"] = cust[0].spec
  1036. applyStyleName(ws["B5"], "border")
  1037. def enableColFunc(ws, code, enableCols):
  1038. global cursor
  1039. global stdSizeMapColumn
  1040. # std sizes
  1041. stdSizes = """
  1042. select * from AllProduct_Dimension_ForInsProcess where ProductCode='{0}'""".format(code.replace("-", ""))
  1043. #print(stdSizes)
  1044. cursor.execute(stdSizes)
  1045. rows = cursor.fetchall()
  1046. for r in rows:
  1047. if r.Size_Name.replace("size", "").replace("Size", "").strip() in stdSizeMapColumn:
  1048. colName = stdSizeMapColumn[r.Size_Name.replace("size", "").replace("Size", "").strip()]
  1049. #print(colName+"12")
  1050. #print(min)
  1051. ws.column_dimensions[colName].hidden = False
  1052. stripSize = r.Size_Name.replace("size", "").replace("Size").strip()
  1053. if stripSize not in enableCols:
  1054. enableCols.append(stripSize)
  1055. def applyStyleName(cell, styleName, format=None):
  1056. cell.style = styleName
  1057. if format is not None:
  1058. #print(format)
  1059. cell.number_format = format
  1060. else:
  1061. cell.number_format = "0.00"
  1062. def createExcelDaily(codeno, filters, segment):
  1063. global cursor
  1064. global wb
  1065. global dateStyle
  1066. #wb["Data Measurement"].sheet_state = 'hidden'
  1067. ws = wb["Daily"]
  1068. codeString = ""
  1069. for idx in range(1, 13):
  1070. ws.row_dimensions[idx].hidden = True
  1071. for k,v in stdSizeMapColumn.items():
  1072. if k not in ["Weight", "Result"]:
  1073. ws.column_dimensions[v].hidden = True
  1074. enableCols = []
  1075. if codeno != "" and codeno != "undefined":
  1076. if codeno.find('-') != -1:
  1077. codeString = codeno
  1078. else:
  1079. codeString = codeno[0] + "-" + codeno[1:5] + "-" + codeno[5:9] + "-" + codeno[9:10]
  1080. # std sizes
  1081. stdSizes = """
  1082. select * from AllProduct_Dimension_ForInsProcess where ProductCode='{0}'""".format(codeString.replace("-", ""))
  1083. #print(stdSizes)
  1084. cursor.execute(stdSizes)
  1085. rows = cursor.fetchall()
  1086. for r in rows:
  1087. minv = float(r.Std) + float(r.TolUn)
  1088. stdv = float(r.Std)
  1089. maxv = float(r.Std) + float(r.TolUp)
  1090. if r.Size_Name.replace("size", "").strip() in stdSizeMapColumn:
  1091. colName = stdSizeMapColumn[r.Size_Name.replace("size", "").strip()]
  1092. #print(colName+"12")
  1093. #print(min)
  1094. ws.column_dimensions[colName].hidden = False
  1095. #ws[colName+"12"] = minv #min
  1096. #ws[colName+"11"] = stdv #std
  1097. #ws[colName+"10"] = maxv #max
  1098. enableCols.append(r.Size_Name.replace("size", "").strip())
  1099. if codeno == "undefined":
  1100. distinct_qt = "select distinct(code) code from data_ms where {1}".format(codeString, filters)
  1101. cursor.execute(distinct_qt)
  1102. rows = cursor.fetchall()
  1103. #print("dist = ", distinct_qt)
  1104. for r in rows:
  1105. enableColFunc(ws, r.code, enableCols)
  1106. maxQuery = [ "max(%ssize) as %s"% ( x.lower(), x.upper() ) for x in enableCols]
  1107. #print(maxQuery)
  1108. if filters is not None:
  1109. if codeno != "undefined":
  1110. qt = "select {2} from data_ms where code='{0}' and {1}".format(codeString, filters, ",".join(maxQuery))
  1111. else:
  1112. qt = "select {2} from data_ms where {1}".format(codeString, filters, ",".join(maxQuery))
  1113. else:
  1114. if codeno != "undefined" and codeno != "":
  1115. qt = "select {1} from data_ms where code='{0}'".format(codeString, ",".join(maxQuery))
  1116. else:
  1117. qt = "select {1} from data_ms".format(codeString, ",".join(maxQuery))
  1118. #print("qt = ", qt)
  1119. cursor.execute(qt)
  1120. rows = cursor.fetchall()
  1121. for r in rows:
  1122. #print(r.cursor_description)
  1123. #enableColFunc(ws, r.code, enableCols)
  1124. for c in r.cursor_description:
  1125. #print(c)
  1126. #print(getattr(r, c[0]))
  1127. if c[0] in stdSizeMapColumn:
  1128. colName = stdSizeMapColumn[c[0]]
  1129. #ws[colName+"8"] = getattr(r, c[0])
  1130. maxQuery = [ "min(%ssize) as %s"% ( x.lower(), x.upper() ) for x in enableCols]
  1131. #print(maxQuery)
  1132. if filters is not None:
  1133. if codeno != "undefined":
  1134. qt = "select {2} from data_ms where code='{0}' and {1}".format(codeString, filters, ",".join(maxQuery))
  1135. else:
  1136. qt = "select {2} from data_ms where {1}".format(codeString, filters, ",".join(maxQuery))
  1137. else:
  1138. if codeno != "undefined":
  1139. qt = "select {1} from data_ms where code='{0}'".format(codeString, ",".join(maxQuery))
  1140. else:
  1141. qt = "select {1} from data_ms".format(codeString, ",".join(maxQuery))
  1142. '''
  1143. if filters is not None:
  1144. qt = "select {2} from data_ms where code='{0}' and {1}".format(codeString, filters, ",".join(maxQuery))
  1145. else:
  1146. qt = "select {1} from data_ms where code='{0}'".format(codeString, ",".join(maxQuery))
  1147. '''
  1148. cursor.execute(qt)
  1149. rows = cursor.fetchall()
  1150. for r in rows:
  1151. #print(r.cursor_description)
  1152. for c in r.cursor_description:
  1153. #print(c)
  1154. #print(getattr(r, c[0]))
  1155. if c[0] in stdSizeMapColumn:
  1156. colName = stdSizeMapColumn[c[0]]
  1157. #ws[colName+"9"] = getattr(r, c[0])
  1158. #query data
  1159. joinString = joinSelect = ""
  1160. #print("segment = ", segment)
  1161. if segment != None:
  1162. joinSelect = ",lt.*"
  1163. joinString = "inner join LotTracking lt on ms.id = lt.datams_id and lt.machineGroup = '{0}'" .format(segment)
  1164. filters = "ms."+filters
  1165. else:
  1166. joinSelect = ",lt.*"
  1167. joinString = "inner join LotTracking lt on ms.id = lt.datams_id" .format(segment)
  1168. filters = "ms."+filters
  1169. #print(joinString)
  1170. if filters is not None:
  1171. if codeno != "undefined":
  1172. qMsData = """
  1173. select ms.* {3} from data_ms ms {2} where code='{0}' and {1} order by lot_no asc, row_no asc
  1174. """.format(codeString, filters, joinString, joinSelect)
  1175. else:
  1176. qMsData = """
  1177. select ms.* {3} from data_ms ms {2} where {1} order by lot_no asc, row_no asc
  1178. """.format(codeString, filters, joinString, joinSelect)
  1179. else:
  1180. if codeno != "undefined":
  1181. qMsData = """
  1182. select ms.* {2} from data_ms ms {1} where code='{0}' order by lot_no asc, row_no asc
  1183. """.format(codeString, joinString, joinSelect)
  1184. else:
  1185. qMsData = """
  1186. select ms.* {2} from data_ms ms {1} order by lot_no asc, row_no asc
  1187. """.format(codeString, joinString, joinSelect)
  1188. #print(qMsData)
  1189. cursor.execute(qMsData)
  1190. rows = cursor.fetchall()
  1191. startRow = 15
  1192. styleName = "border"
  1193. for r in rows:
  1194. isNG = False
  1195. '''
  1196. if r.dsize == 0 and r.hsize == 0 and r.tsize == 0:
  1197. continue
  1198. '''
  1199. if int(r.row_no) == 1:
  1200. ws.cell(column = 1, row = startRow, value = r.created_at).number_format = "m/d/yy"
  1201. ws.cell(column = 1, row = startRow).style = styleName
  1202. ws.cell(column = 2, row = startRow, value = r.code)
  1203. ws.cell(column = 2, row = startRow).style = styleName
  1204. ws.cell(column = 3, row = startRow, value=r.lot_no)
  1205. ws.cell(column = 3, row = startRow).style = styleName
  1206. countLot = """
  1207. select count(*) as c from data_ms where lot_no = '{0}'
  1208. """.format(r.lot_no)
  1209. cursor.execute(countLot)
  1210. countResult = cursor.fetchall()
  1211. #print(countResult)
  1212. ws.cell(column = 4, row = startRow, value = countResult[0].c).number_format = "0"
  1213. ws.cell(column = 4, row = startRow).style = styleName
  1214. c = ws.cell(column=5, row = startRow, value = int(r.row_no))
  1215. c.style = styleName
  1216. c.number_format = "0"
  1217. ws["AJ"+str(startRow)] = r.emp_id
  1218. ws["AJ"+str(startRow)].style = styleName
  1219. ws["AK"+str(startRow)] = r.created_at
  1220. applyStyleName(ws["AK"+str(startRow)], styleName, FORMAT_DATE_DATETIME)
  1221. colstr = stdSizeMapColumn.get("D")
  1222. ws[colstr + str(startRow)] = r.dsize
  1223. applyStyleName(ws[colstr + str(startRow)], styleName)
  1224. if r.dsizeOk == "NG":
  1225. isNG = True
  1226. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  1227. colstr = stdSizeMapColumn.get("T")
  1228. ws[colstr + str(startRow)] = r.tsize
  1229. applyStyleName(ws[colstr + str(startRow)], styleName)
  1230. if r.tsizeOk == "NG":
  1231. isNG = True
  1232. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  1233. colstr = stdSizeMapColumn.get("H")
  1234. applyStyleName(ws[colstr + str(startRow)], styleName)
  1235. if ( r.hdev is not None) and ( r.hsizeproxy is not None ) and (r.hsizeproxy != 'null') and ( r.hdev.strip() != "") and (r.hdev.strip() != 'null'):
  1236. ws[colstr + str(startRow)] = "%s/%s" % (r.hsizeproxy.strip(), r.hdev.strip())
  1237. else:
  1238. if ( r.hsizeproxy is not None ) and ( r.hsizeproxy.strip() != 'null'):
  1239. proxyStrip = r.hsizeproxy.strip()
  1240. if proxyStrip == "OK" or proxyStrip == "NG":
  1241. ws[colstr + str(startRow)] = proxyStrip
  1242. else:
  1243. try:
  1244. ws[colstr + str(startRow)] = float(proxyStrip.replace("+", ""))
  1245. except Exception as e:
  1246. pass
  1247. if r.hsizeOk == "NG":
  1248. isNG = True
  1249. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  1250. colstr = stdSizeMapColumn.get("C")
  1251. applyStyleName(ws[colstr + str(startRow)], styleName)
  1252. ws[colstr + str(startRow)] = r.csize
  1253. if r.csizeOk == "NG":
  1254. isNG = True
  1255. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  1256. colstr = stdSizeMapColumn.get("E")
  1257. applyStyleName(ws[colstr + str(startRow)], styleName)
  1258. ws[colstr + str(startRow)] = r.esize
  1259. if r.esizeOk == "NG":
  1260. isNG = True
  1261. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  1262. colstr = stdSizeMapColumn.get("F")
  1263. applyStyleName(ws[colstr + str(startRow)], styleName)
  1264. ws[colstr + str(startRow)] = r.fsize
  1265. if r.fsizeOk == "NG":
  1266. isNG = True
  1267. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  1268. colstr = stdSizeMapColumn.get("G")
  1269. applyStyleName(ws[colstr + str(startRow)], styleName)
  1270. ws[colstr + str(startRow)] = r.gsize
  1271. if r.gsizeOk == "NG":
  1272. isNG = True
  1273. ws[colstr + str(startRow)].font = Font(color = colors.RED)
  1274. colstr = stdSizeMapColumn.get("J")
  1275. applyStyleName(ws[colstr + str(startRow)], styleName)
  1276. ws[colstr+str(startRow)] = r.jsize
  1277. if r.jsizeOk == "NG":
  1278. isNG = True
  1279. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1280. colstr = stdSizeMapColumn.get("K")
  1281. applyStyleName(ws[colstr + str(startRow)], styleName)
  1282. ws[colstr+str(startRow)] = r.ksize
  1283. if r.ksizeOk == "NG":
  1284. isNG = True
  1285. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1286. colstr = stdSizeMapColumn.get("M")
  1287. applyStyleName(ws[colstr + str(startRow)], styleName)
  1288. ws[colstr+str(startRow)] = r.msize
  1289. if r.msizeOk == "NG":
  1290. isNG = True
  1291. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1292. colstr = stdSizeMapColumn.get("N")
  1293. applyStyleName(ws[colstr + str(startRow)], styleName)
  1294. ws[colstr+str(startRow)] = r.nsize
  1295. if r.nsizeOk == "NG":
  1296. isNG = True
  1297. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1298. colstr = stdSizeMapColumn.get("P")
  1299. applyStyleName(ws[colstr + str(startRow)], styleName)
  1300. ws[colstr+str(startRow)] = r.psize
  1301. if r.psizeOk == "NG":
  1302. isNG = True
  1303. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1304. colstr = stdSizeMapColumn.get("U")
  1305. applyStyleName(ws[colstr + str(startRow)], styleName)
  1306. ws[colstr+str(startRow)] = r.usize
  1307. if r.usizeOk == "NG":
  1308. isNG = True
  1309. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1310. colstr = stdSizeMapColumn.get("W")
  1311. applyStyleName(ws[colstr + str(startRow)], styleName)
  1312. ws[colstr+str(startRow)] = r.wsize
  1313. if r.wsizeOk == "NG":
  1314. isNG = True
  1315. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1316. colstr = stdSizeMapColumn.get("Weight")
  1317. applyStyleName(ws[colstr + str(startRow)], styleName)
  1318. ws[colstr+str(startRow)] = r.weight
  1319. colstr = stdSizeMapColumn.get("Result")
  1320. applyStyleName(ws[colstr + str(startRow)], styleName)
  1321. if isNG == True:
  1322. ws[colstr+ str(startRow)] = "NG"
  1323. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1324. else:
  1325. ws[colstr+ str(startRow)] = "OK"
  1326. '''
  1327. colstr = stdSizeMapColumn.get("X")
  1328. ws[colstr+str(startRow)].value = r.xsize
  1329. if r.xsizeOk == "NG":
  1330. ws[colstr+ str(startRow)].font = Font(color = colors.RED)
  1331. '''
  1332. #ws['U'+str(startRow)] = r.ysize or 0
  1333. #ysize.font= Font(color = colors.Red)
  1334. #ws['V'+str(startRow)] = r.
  1335. #print(wb.style_names)
  1336. #print(ws["AJ"+str(startRow)].style)
  1337. ws["AJ"+str(startRow)] = r.emp_id
  1338. ws["AJ"+str(startRow)].style = styleName
  1339. ws["AK"+str(startRow)] = r.created_at
  1340. applyStyleName(ws["AK"+str(startRow)], styleName, FORMAT_DATE_DATETIME)
  1341. ws["AL"+str(startRow)] = "Dimension out of specs" if isNG else ""
  1342. applyStyleName(ws["AL"+str(startRow)], styleName)
  1343. ws["AN"+str(startRow)] = str(r.machineId)
  1344. applyStyleName(ws["AN"+str(startRow)], styleName)
  1345. ws["AO"+str(startRow)] = str(r.machineGroup)
  1346. applyStyleName(ws["AO"+str(startRow)], styleName)
  1347. startRow += 1
  1348. #print(ws._charts)
  1349. if codeno != "undefined":
  1350. cust = findCustomer(codeno.replace("-", ""))
  1351. ws["B3"] = codeno.replace("-", "")
  1352. if cust:
  1353. ws["B2"] = cust[0].customer
  1354. ws["B4"] = cust[0].sizestring
  1355. ws["B5"] = cust[0].spec
  1356. if __name__ == "__main__":
  1357. env = sys.argv[1]
  1358. code = sys.argv[2]
  1359. #print(len(sys.argv))
  1360. df = None
  1361. segment = None
  1362. #print(len(sys.argv))
  1363. if len(sys.argv) > 3:
  1364. filter = sys.argv[3]
  1365. #import ast
  1366. #df = ast.literal_eval(filter)
  1367. #print(df['date'])
  1368. df = filter
  1369. if len(sys.argv) > 4:
  1370. segment = sys.argv[4]
  1371. global cnxn
  1372. global cursor
  1373. if env == "prod":
  1374. cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=192.168.0.253;DATABASE=OB2011DB;UID=user1;PWD=1234')
  1375. cursor = cnxn.cursor()
  1376. else:
  1377. cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=OB2011DB;UID=admin;PWD=1234')
  1378. cursor = cnxn.cursor()
  1379. #print("code is "+code)
  1380. if code != "undefined" and code != "":
  1381. wb["Daily"].sheet_state = "hidden"
  1382. createExcel(code, df)
  1383. createChart(code, df)
  1384. createXBarChart(code, df)
  1385. #createCp(code, df)
  1386. else:
  1387. wb["Data Measurement"].sheet_state = "hidden"
  1388. wb["Chart"].sheet_state = "hidden"
  1389. createExcelDaily(code, df, segment);
  1390. #createXRangeChart(code, df)
  1391. '''
  1392. thin_border = Border(left=Side(style='thick'),
  1393. right=Side(style='thick'),
  1394. top=Side(style='thick'),
  1395. bottom=Side(style='thick'))
  1396. wtd['C1'].value = 1234
  1397. wtd["C1"].border = thin_border
  1398. wtd['D1'].value = "Hello"
  1399. '''
  1400. #print wb.get_sheet_names()
  1401. #print wb0.get_sheet_names()
  1402. ut = int(time.time())
  1403. if code != "undefined":
  1404. filename = "measurement{0}_{1}.xlsx".format(code.replace("-", ""), ut)
  1405. else:
  1406. filename = "measurement_{1}.xlsx".format(code.replace("-", ""), ut)
  1407. outfile = './public/excel/'+filename
  1408. wb.save(filename = outfile)
  1409. wb.close()
  1410. print(filename)