Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ipipan/valunifer
1 result
Show changes
Commits on Source (11)
Showing
with 241 additions and 22 deletions
/*! Split.js - v1.6.5 */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Split=t()}(this,(function(){"use strict";var e="undefined"!=typeof window?window:null,t=null===e,n=t?void 0:e.document,i=function(){return!1},r=t?"calc":["","-webkit-","-moz-","-o-"].filter((function(e){var t=n.createElement("div");return t.style.cssText="width:"+e+"calc(9px)",!!t.style.length})).shift()+"calc",s=function(e){return"string"==typeof e||e instanceof String},o=function(e){if(s(e)){var t=n.querySelector(e);if(!t)throw new Error("Selector "+e+" did not match a DOM element");return t}return e},a=function(e,t,n){var i=e[t];return void 0!==i?i:n},u=function(e,t,n,i){if(t){if("end"===i)return 0;if("center"===i)return e/2}else if(n){if("start"===i)return 0;if("center"===i)return e/2}return e},l=function(e,t){var i=n.createElement("div");return i.className="gutter gutter-"+t,i},c=function(e,t,n){var i={};return s(t)?i[e]=t:i[e]=r+"("+t+"% - "+n+"px)",i},h=function(e,t){var n;return(n={})[e]=t+"px",n};return function(r,s){if(void 0===s&&(s={}),t)return{};var f,d,v,m,g,p,y=r;Array.from&&(y=Array.from(y));var z=o(y[0]).parentNode,S=getComputedStyle?getComputedStyle(z):null,b=S?S.flexDirection:null,E=a(s,"sizes")||y.map((function(){return 100/y.length})),_=a(s,"minSize",100),L=Array.isArray(_)?_:y.map((function(){return _})),w=a(s,"maxSize",1/0),x=Array.isArray(w)?w:y.map((function(){return w})),O=a(s,"expandToMin",!1),A=a(s,"gutterSize",10),k=a(s,"gutterAlign","center"),C=a(s,"snapOffset",30),M=Array.isArray(C)?C:y.map((function(){return C})),U=a(s,"dragInterval",1),D=a(s,"direction","horizontal"),B=a(s,"cursor","horizontal"===D?"col-resize":"row-resize"),T=a(s,"gutter",l),j=a(s,"elementStyle",c),F=a(s,"gutterStyle",h);function R(e,t,n,i){var r=j(f,t,n,i);Object.keys(r).forEach((function(t){e.style[t]=r[t]}))}function N(){return p.map((function(e){return e.size}))}function q(e){return"touches"in e?e.touches[0][d]:e[d]}function H(e){var t=p[this.a],n=p[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,R(t.element,t.size,this._b,t.i),R(n.element,n.size,this._c,n.i)}function I(e){var t,n=p[this.a],r=p[this.b];this.dragging&&(t=q(e)-this.start+(this._b-this.dragOffset),U>1&&(t=Math.round(t/U)*U),t<=n.minSize+n.snapOffset+this._b?t=n.minSize+this._b:t>=this.size-(r.minSize+r.snapOffset+this._c)&&(t=this.size-(r.minSize+this._c)),t>=n.maxSize-n.snapOffset+this._b?t=n.maxSize+this._b:t<=this.size-(r.maxSize-r.snapOffset+this._c)&&(t=this.size-(r.maxSize+this._c)),H.call(this,t),a(s,"onDrag",i)(N()))}function W(){var e=p[this.a].element,t=p[this.b].element,n=e.getBoundingClientRect(),i=t.getBoundingClientRect();this.size=n[f]+i[f]+this._b+this._c,this.start=n[v],this.end=n[m]}function X(e){var t=function(e){if(!getComputedStyle)return null;var t=getComputedStyle(e);if(!t)return null;var n=e[g];return 0===n?null:n-="horizontal"===D?parseFloat(t.paddingLeft)+parseFloat(t.paddingRight):parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)}(z);if(null===t)return e;if(L.reduce((function(e,t){return e+t}),0)>t)return e;var n=0,i=[],r=e.map((function(r,s){var o=t*r/100,a=u(A,0===s,s===e.length-1,k),l=L[s]+a;return o<l?(n+=l-o,i.push(0),l):(i.push(o-l),o)}));return 0===n?e:r.map((function(e,r){var s=e;if(n>0&&i[r]-n>0){var o=Math.min(n,i[r]-n);n-=o,s=e-o}return s/t*100}))}function Y(){var t=p[this.a].element,r=p[this.b].element;this.dragging&&a(s,"onDragEnd",i)(N()),this.dragging=!1,e.removeEventListener("mouseup",this.stop),e.removeEventListener("touchend",this.stop),e.removeEventListener("touchcancel",this.stop),e.removeEventListener("mousemove",this.move),e.removeEventListener("touchmove",this.move),this.stop=null,this.move=null,t.removeEventListener("selectstart",i),t.removeEventListener("dragstart",i),r.removeEventListener("selectstart",i),r.removeEventListener("dragstart",i),t.style.userSelect="",t.style.webkitUserSelect="",t.style.MozUserSelect="",t.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",this.gutter.style.cursor="",this.parent.style.cursor="",n.body.style.cursor=""}function G(t){if(!("button"in t)||0===t.button){var r=p[this.a].element,o=p[this.b].element;this.dragging||a(s,"onDragStart",i)(N()),t.preventDefault(),this.dragging=!0,this.move=I.bind(this),this.stop=Y.bind(this),e.addEventListener("mouseup",this.stop),e.addEventListener("touchend",this.stop),e.addEventListener("touchcancel",this.stop),e.addEventListener("mousemove",this.move),e.addEventListener("touchmove",this.move),r.addEventListener("selectstart",i),r.addEventListener("dragstart",i),o.addEventListener("selectstart",i),o.addEventListener("dragstart",i),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",this.gutter.style.cursor=B,this.parent.style.cursor=B,n.body.style.cursor=B,W.call(this),this.dragOffset=q(t)-this.end}}"horizontal"===D?(f="width",d="clientX",v="left",m="right",g="clientWidth"):"vertical"===D&&(f="height",d="clientY",v="top",m="bottom",g="clientHeight"),E=X(E);var J=[];function K(e){var t=e.i===J.length,n=t?J[e.i-1]:J[e.i];W.call(n);var i=t?n.size-e.minSize-n._c:e.minSize+n._b;H.call(n,i)}return(p=y.map((function(e,t){var n,i={element:o(e),size:E[t],minSize:L[t],maxSize:x[t],snapOffset:M[t],i:t};if(t>0&&((n={a:t-1,b:t,dragging:!1,direction:D,parent:z})._b=u(A,t-1==0,!1,k),n._c=u(A,!1,t===y.length-1,k),"row-reverse"===b||"column-reverse"===b)){var r=n.a;n.a=n.b,n.b=r}if(t>0){var s=T(t,D,i.element);!function(e,t,n){var i=F(f,t,n);Object.keys(i).forEach((function(t){e.style[t]=i[t]}))}(s,A,t),n._a=G.bind(n),s.addEventListener("mousedown",n._a),s.addEventListener("touchstart",n._a),z.insertBefore(s,i.element),n.gutter=s}return R(i.element,i.size,u(A,0===t,t===y.length-1,k),t),t>0&&J.push(n),i}))).forEach((function(e){var t=e.element.getBoundingClientRect()[f];t<e.minSize&&(O?K(e):e.minSize=t)})),{setSizes:function(e){var t=X(e);t.forEach((function(e,n){if(n>0){var i=J[n-1],r=p[i.a],s=p[i.b];r.size=t[n-1],s.size=e,R(r.element,r.size,i._b,r.i),R(s.element,s.size,i._c,s.i)}}))},getSizes:N,collapse:function(e){K(p[e])},destroy:function(e,t){J.forEach((function(n){if(!0!==t?n.parent.removeChild(n.gutter):(n.gutter.removeEventListener("mousedown",n._a),n.gutter.removeEventListener("touchstart",n._a)),!0!==e){var i=j(f,n.a.size,n._b);Object.keys(i).forEach((function(e){p[n.a].element.style[e]="",p[n.b].element.style[e]=""}))}}))},parent:z,pairs:J}}}));
......@@ -76,6 +76,11 @@
</a>
</li>
{% endif %}
<li class="nav-item" id="nav-fin-statements">
<a class="nav-link text-light" href="{% url 'financial_settlement:statement_list' %}">
{% trans "Umowy" %}
</a>
</li>
</ul>
{% endif %}
</div>
......
......@@ -8,6 +8,7 @@ services:
postgresql:
container_name: shellvalier-postgresql
image: postgres:14.2
shm_size: 1gb
environment:
POSTGRES_USER: "shellvalier"
POSTGRES_DB: "shellvalier"
......@@ -33,7 +34,7 @@ services:
volumes:
- .:/app
ports:
- "8000:8000"
- "80:8000"
frontend:
container_name: shellvalier-frontend
......
......@@ -30,7 +30,6 @@ class CheckboxesLayoutField(object):
else:
return layout.Field(x, **kwargs)
class RadiosLayoutField(object):
def layout(self, x, **kwargs):
......
......@@ -624,12 +624,16 @@ class UnifiedFrameFormFactory(FormFactory):
field_makers = (
(
'status',
lambda: ModelMultipleChoiceFilter(
lambda: MultipleChoiceFilter(
label=_('Status'),
queryset=UnifiedFrame.objects.distinct(),
key='status',
choices=(
(UnifiedFrameStatus.PROCESSING, (_('W obróbce'), None)),
(UnifiedFrameStatus.READY, (_('Gotowe'), None)),
(UnifiedFrameStatus.VERIFIED, (_('Sprawdzone'), None)),
),
lookup='status',
), None,
),
None,
),
(
None, None,
......
......@@ -184,6 +184,18 @@ legend {
border-color: #564c4c;
}
.active-lu {
font-weight: bold;
}
.lu-underline {
text-decoration: underline;
}
.cursor-pointer {
cursor: pointer;
}
.sticky-bottom {
position: sticky;
bottom: 0;
......@@ -264,3 +276,13 @@ legend {
accent-color: green;
pointer-events: none;
}
.hierarchy_not_exists {
background-color: rgba(138, 11, 17, 0.14) !important;
}
.table-primary,
.table-primary>td,
.table-primary>th {
background-color:#bfbfbf !important;
}
......@@ -1004,6 +1004,9 @@ function setup_datatable(options) {
{
$(this).removeClass('tr-hover');
});
if (options.setup_hierarchy_marking === true && data.hierarchy_exists !== true) {
$(row).addClass('hierarchy_not_exists');
}
},
initComplete: function(settings, json) {
// display the first entry once it’s loaded
......@@ -1090,7 +1093,7 @@ function initialize_entries_list() {
function getRoles() {
$.ajax({
dataType: "json",
url: 'roles',
url: '/' + lang + '/entries/roles',
success: function(data){
roles = data.roles;
},
......@@ -1101,7 +1104,7 @@ function getRoles() {
function getRoleAttributes() {
$.ajax({
dataType: "json",
url: 'role_attributes',
url: '/' + lang + '/entries/role_attributes',
success: function(data){
role_attributes = data.role_attributes;
},
......@@ -1136,9 +1139,9 @@ $(document).ready(function() {
// getPredefinedSelections();
// getRoles();
//
// getRoleAttributes();
getRoles();
getRoleAttributes();
// $.getJSON('relations', function(data){
// memorizeRelations(data.relations);
......
function update_entries() {
function update_entries2() {
var datatable = setup_datatable({
element: $("#entries-table"),
selectFirst: true,
......
......@@ -84,7 +84,7 @@ function setup_lexical_units_table(drilldown, lexical_units, can_see_assignees,
});
}
function show_notes_form($container, pk, model, refreshFunction, title, body) {
function show_notes_form($container, pk, model, refreshFunction, type, title, body) {
$('.note-form', $container).html($('#note-form-template > div', $container).clone());
$('.hide-note-form', $container).click(function () {
$('.note-form', $container).html('');
......@@ -92,7 +92,7 @@ function show_notes_form($container, pk, model, refreshFunction, title, body) {
$('.add-note', $container).click(function () {
$.ajax({
type: 'post',
url: $('#note-form-template').data('url').replace('MODEL', model).replace('PK', pk),
url: $('#note-form-template').data('url').replace('MODEL', model).replace('PK', pk).replace('TYPE', type),
dataType: 'json',
data: {
title: $('.note-form input[name=title]').val(),
......@@ -117,18 +117,18 @@ function show_notes_form($container, pk, model, refreshFunction, title, body) {
}
}
function setup_notes($container, $template, pk, model, refreshFunction, title, body) {
function setup_notes($container, $template, pk, model, refreshFunction, type, title, body) {
$container.html($template.children().clone());
$('.show-note-form', $container).click(function () {
show_notes_form($container, pk, model, refreshFunction, title, body);
show_notes_form($container, pk, model, refreshFunction, type, title, body);
return false
});
if(title || body) {
show_notes_form($container, pk, model, refreshFunction, title, body);
show_notes_form($container, pk, model, refreshFunction, type, title, body);
}
$.ajax({
type: 'get',
url: $('.notes-table').data('url').replace('MODEL', model).replace('PK', pk),
url: $('.notes-table').data('url').replace('MODEL', model).replace('PK', pk).replace('TYPE', type),
success: function (data) {
data.notes.map(function (note) {
$('.notes-table tbody', $container).append(
......
......@@ -19,7 +19,9 @@ function setup_frames_list(options) {
can_see_assignees ? { data: 'assignee_username' } : { render: is_assigned_to_user_renderer },
{ data: 'id' },
],
hidden_columns: can_see_assignees ? [3] : [2,3]
hidden_columns: can_see_assignees ? [3] : [2,3],
selectEntryId: options.selectEntryId,
setup_hierarchy_marking: true
});
datatable.on('click', 'tr.entry', function () {
const data = datatable.row(this).data();
......
......@@ -17,7 +17,7 @@
{% block scripts %}
<!-- https://www.cssscript.com/split-view/ -->
<script src="https://unpkg.com/split.js/dist/split.min.js"></script>
<script src="{% static 'common/js/split.min.js' %}"></script>
<!-- https://datatables.net/ -->
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.12.1/sc-2.0.3/datatables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.12.1/features/scrollResize/dataTables.scrollResize.min.js"></script>
......@@ -30,6 +30,10 @@
{% block additional-nav-items %}
{% if request.user.is_authenticated %}
<li class="nav-item"><a href="{% url 'entries:unification' %}" class="nav-link">{% trans "Unifikacja" %}</a></li>
<li class="nav-item"><a
onclick='window.location.replace(window.currUnifiedFrameId ? "/pl/entries/hierarchy/?unified_frame_id="+window.currUnifiedFrameId : "/pl/entries/hierarchy")'
class="nav-link cursor-pointer">{% trans "Hierarchia" %}</a></li>
{% endif %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="nav-filters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
......
{% extends "entries_base.html" %}
{% load i18n %}
{% load static %}
{% block title %}{% trans "Hasła" %}{% endblock %}
{% block scripts %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'entries/css/unification_frames.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'common/css/role_colours.css' %}">
<script src="{% static 'entries/js/unification_entries_list.js' %}"></script>
<script src="{% static 'entries/js/unification_frames_list.js' %}"></script>
<script src="{% static 'entries/js/unification_entries_for_frames_list.js' %}"></script>
<script src="{% static 'entries/js/jquery-impromptu.min.js' %}"></script>
<script>
window.currUnifiedFrameId = {{ unified_frame_id|default:'null' }};
</script>
{% endblock %}
{% block modals %}
{{ block.super }}
<div id="lexical-unit-notes-template" class="d-none">{% include 'notes.html' %}</div>
{% endblock %}
......@@ -18,6 +18,7 @@ urlpatterns = [
path('change_show_reals_desc/', views.change_show_reals_desc, name='change_show_reals_desc'),
path('change_show_linked_entries/', views.change_show_linked_entries, name='change_show_linked_entries'),
path('unification/', views.unification, name='unification'),
path('hierarchy/', views.hierarchy, name='hierarchy'),
path('autocomplete/', autocompletes.autocomplete, name='autocomplete'),
path('plWN_context_lookup/', ajax_plWN_context_lookup, name='plWN_context_lookup'),
......
......@@ -87,10 +87,32 @@ def unification(request):
)
@login_required
def hierarchy(request):
unified_frame_id = None
if "unified_frame_id" in request.GET:
unified_frame_id = request.GET.get("unified_frame_id")
return render(
request,
'hierarchy.html',
{
'is_vue_app': True,
'unified_frame_id': unified_frame_id,
'entries_form': EntryForm(),
'frames_form': FrameFormFactory.get_form(as_subform=False),
'schemata_form': SchemaFormFactory.get_form(as_subform=False),
'unified_frames_form': UnifiedFrameFormFactory.get_form(as_subform=False),
},
)
FORM_TYPES = {
'entry' : EntryForm,
}
FORM_FACTORY_TYPES = {
'schema' : SchemaFormFactory,
'position' : PositionFormFactory,
......@@ -108,14 +130,12 @@ FORM_FACTORY_TYPES = {
def make_form(form_type, data=None, unique_number=None):
#print('======== MAKE FORM', form_type)
if form_type in FORM_FACTORY_TYPES:
return FORM_FACTORY_TYPES[form_type].get_form(data=data, unique_number=unique_number)
if form_type in FORM_TYPES:
return FORM_TYPES[form_type](data=data)
elif form_type.startswith('phrase_'):
phrase_type = form_type[7:]
#print('================ MAKE PHRASE FORM', phrase_type, unique_number)
return PhraseAttributesFormFactory.get_form(phrase_type, data=data, unique_number=unique_number)
return None
......
from django.apps import AppConfig
class FinStatementConfig(AppConfig):
name = 'financial_settlement'
from django import forms
from django.contrib.auth.models import Group, User
from django.urls import reverse_lazy
from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Layout, Fieldset, ButtonHolder, Submit
from financial_settlement.models import FinStatement
from users.models import Note
class FinStatementForm(forms.ModelForm):
start_date = forms.DateTimeField(input_formats=['%d-%m-%Y'],
widget=forms.DateTimeInput(format='%d-%m-%Y', attrs={'class': 'form-control'}))
end_date = forms.DateTimeField(input_formats=['%d-%m-%Y'],
widget=forms.DateTimeInput(
format='%d-%m-%Y', attrs={'class': 'form-control'}))
user = forms.ModelChoiceField(queryset=User.objects.all(), label=_('Użytkownik'))
is_active = forms.CheckboxInput()
class Meta:
model = FinStatement
fields = [
'statement_id',
'title',
'start_date',
'end_date',
'payment',
'last_statement_payment',
'price_per_unified_frame',
'user',
'is_active'
]
def __init__(self, *args, instance, **kwargs):
super().__init__(*args, instance=instance, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset('', 'statement_id', 'title', 'start_date', 'end_date',
'payment', 'price_per_unified_frame', 'last_statement_payment', 'user', 'is_active'),
ButtonHolder(
Submit('submit', _('Zapisz'), css_class='btn btn-sm btn-success'),
HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>',
reverse_lazy('financial_settlement:statement_list'), _('Wróć'))),
),
)
for field in ['statement_id', 'title', 'start_date', 'end_date', 'payment', 'price_per_unified_frame', 'user']:
self.fields[field].required = True
if instance.pk:
self.initial['user'] = instance.user
self.initial['is_active'] = instance.is_active
else:
self.initial['is_active'] = False
def save(self, commit=True):
instance = super().save(commit=commit)
return instance
from django.contrib.auth.models import User
from django.db import models
class FinStatement(models.Model):
"""" Class represents finance statement assigned to the user. """
statement_id = models.PositiveIntegerField(null=False)
title = models.CharField(max_length=200, default=None, blank=True, null=True)
start_date = models.DateField(null=False)
end_date = models.DateField(null=False)
payment = models.DecimalField(null=False, default=0, max_digits=10, decimal_places=3)
price_per_unified_frame = models.DecimalField(null=False, default=0, max_digits=10, decimal_places=3)
last_statement_payment = models.DecimalField(null=False, default=0, max_digits=10, decimal_places=3)
user = models.ForeignKey(User, on_delete=models.PROTECT, default=None, blank=True, null=True)
is_active = models.BooleanField(default=False)
def __str__(self):
return '%s: %s' % (self.statement_id, self.title)
{% extends 'base-margins.html' %}
{% load i18n %}
{% block title %}{% trans 'Szczegóły umowy' %}{% endblock %}
{% block content2 %}
<div class="mt-3">
<h5 class="float-left mt-2">{% trans 'Szczegóły umowy' %}</h5>
</div>
<table class="table" style="display: inline-flex;">
<tbody>
<tr>
<td>{% trans 'Nr umowy' %}</td><td>{{ statement.statement_id }}</td>
</tr>
<tr>
<td>{% trans 'Tytuł umowy' %}</td><td>{{ statement.title }}</td>
</tr>
<tr>
<td>{% trans 'Użytkownik' %}</td><td>{{ statement.user.username }}</td>
</tr>
<tr>
<td>{% trans 'Od' %}</td><td>{{ statement.start_date }}</td>
</tr>
<tr>
<td>{% trans 'Do' %}</td><td>{{ statement.end_date }}</td>
</tr>
<tr>
<td>{% trans 'Kwota' %}</td><td>{{ statement.payment }}</td>
</tr>
<tr>
<td>{% trans 'Koszt anotacji' %}</td><td>{{ statement.price_per_unified_frame }}</td>
</tr>
<tr>
<td>{% trans 'Liczba wykonanych anotacji' %}</td><td>{{ unified_frame_count }}</td>
</tr>
<tr>
<td>{% trans 'Kwota wykorzystana' %}</td><td>{{ current_cost }}</td>
</tr>
<tr>
<td>{% trans 'Kwota z poprzedniej umowy' %}</td><td>{{ statement.last_statement_payment }}</td>
</tr>
</tbody>
</table>
{% endblock %}