Josef Rokos 9 years ago
commit 67ff54d3f1

@ -24,7 +24,7 @@
<repository>
<id>fdvsolution.public</id>
<name>Dynamic Jasper</name>
<url>http://archiva.fdvs.com.ar/repository/public1/</url>
<url>http://nexus.fdvs.com.ar/content/groups/public/</url>
</repository>
</repositories>
@ -407,6 +407,22 @@
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.js</include>
<include>**/*.wpd</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
<dependencyManagement>
<dependencies>

@ -23,4 +23,12 @@ public interface InvoicingService extends Service<Invoicing> {
public List<Invoicing> getArchiveList();
public Invoicing getForRequirement(Requirement req);
public List<Invoicing> getMaterialPendingList();
public List<Invoicing> getMaterialArchiveList();
public List<Invoicing> getServicesPendingList();
public List<Invoicing> getServicesArchiveList();
}

@ -1,5 +1,6 @@
package info.bukova.isspst.services.invoicing;
import info.bukova.isspst.Constants;
import info.bukova.isspst.data.Invoicing;
import info.bukova.isspst.data.InvoicingItem;
import info.bukova.isspst.data.Requirement;
@ -101,4 +102,44 @@ public class InvoicingServiceImpl extends AbstractOwnedService<Invoicing> implem
return (Invoicing) query.uniqueResult();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getMaterialPendingList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed Is Null or inv.completed = false) and (rq.kind = :kind) order by rq.numser");
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getMaterialArchiveList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed = true) and (rq.kind = :kind) order by rq.numser");
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getServicesPendingList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed Is Null or inv.completed = false) and (rq.kind = :kind) order by rq.numser");
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getServicesArchiveList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed = true) and (rq.kind = :kind) order by rq.numser");
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
}
}

@ -29,7 +29,6 @@ public class InvoicingList extends ListViewModel<Invoicing> {
public void initInvoicing() {
service = invoicingService;
dataClass = Invoicing.class;
formZul = "invoicingForm.zul";
dataFilter = new InvoicingFilter(getFilterTemplate());
}

@ -0,0 +1,30 @@
package info.bukova.isspst.ui.main.invoicing;
import info.bukova.isspst.data.Invoicing;
import org.springframework.security.access.AccessDeniedException;
import org.zkoss.bind.annotation.Init;
import java.util.ArrayList;
import java.util.List;
public class InvoicingMaterialArchiveList extends InvoicingList {
@Init(superclass = true)
public void initInvoicingMaterialArchiveList()
{
formZul = "/main/invoicing/material/invHeadForm.zul";
}
@Override
protected List<Invoicing> getListFromService() {
try
{
return invoicingService.getMaterialArchiveList();
}
catch (AccessDeniedException e)
{
e.printStackTrace();
return new ArrayList<Invoicing>();
}
}
}

@ -0,0 +1,30 @@
package info.bukova.isspst.ui.main.invoicing;
import info.bukova.isspst.data.Invoicing;
import org.springframework.security.access.AccessDeniedException;
import org.zkoss.bind.annotation.Init;
import java.util.ArrayList;
import java.util.List;
public class InvoicingMaterialPendingList extends InvoicingList {
@Init(superclass = true)
public void initInvoicingMaterialPendingList()
{
formZul = "/main/invoicing/material/invHeadForm.zul";
}
@Override
protected List<Invoicing> getListFromService() {
try
{
return invoicingService.getMaterialPendingList();
}
catch (AccessDeniedException e)
{
e.printStackTrace();
return new ArrayList<Invoicing>();
}
}
}

@ -1,32 +0,0 @@
package info.bukova.isspst.ui.main.invoicing;
import info.bukova.isspst.data.Invoicing;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.access.AccessDeniedException;
import org.zkoss.bind.annotation.Init;
public class InvoicingPendingList extends InvoicingList
{
@Init(superclass = true)
public void initInvoicingPendingList()
{
}
@Override
protected List<Invoicing> getListFromService()
{
try
{
return invoicingService.getPendingList();
}
catch (AccessDeniedException e)
{
// BindUtils.postGlobalCommand(null, null, "disableCentre", null);
// e.printStackTrace();
return new ArrayList<Invoicing>();
}
}
}

@ -0,0 +1,30 @@
package info.bukova.isspst.ui.main.invoicing;
import info.bukova.isspst.data.Invoicing;
import org.springframework.security.access.AccessDeniedException;
import org.zkoss.bind.annotation.Init;
import java.util.ArrayList;
import java.util.List;
public class InvoicingServicesArchiveList extends InvoicingList {
@Init(superclass = true)
public void initInvoicingServicesArchiveList()
{
formZul = "/main/invoicing/services/invHeadForm.zul";
}
@Override
protected List<Invoicing> getListFromService() {
try
{
return invoicingService.getServicesArchiveList();
}
catch (AccessDeniedException e)
{
e.printStackTrace();
return new ArrayList<Invoicing>();
}
}
}

@ -0,0 +1,30 @@
package info.bukova.isspst.ui.main.invoicing;
import info.bukova.isspst.data.Invoicing;
import org.springframework.security.access.AccessDeniedException;
import org.zkoss.bind.annotation.Init;
import java.util.ArrayList;
import java.util.List;
public class InvoicingServicesPendingList extends InvoicingList {
@Init(superclass = true)
public void initInvoicingServicesPendingList()
{
formZul = "/main/invoicing/services/invHeadForm.zul";
}
@Override
protected List<Invoicing> getListFromService() {
try
{
return invoicingService.getServicesPendingList();
}
catch (AccessDeniedException e)
{
e.printStackTrace();
return new ArrayList<Invoicing>();
}
}
}

@ -392,6 +392,9 @@ InvoicingDescription=Popis
InvoicingInvoiced=Fakturováno
InvoicingApplicant=Žadatel
InvoicingMaterial=Fakturace požadavků na materiál
InvoicingServices=Fakturace požadavků na servis
HandleComboKeyFilter=#del
HandleComboKey=$#del

@ -1,3 +1,3 @@
storage.root=/home/pepa/tmp/isspst
storage.fulltextIndex=/home/pepa/tmp/isspst
storage.signedDocuments=/home/pepa/tmp/isspst/signedDoc
storage.root=~/tmp/isspst
storage.fulltextIndex=~/tmp/isspst
storage.signedDocuments=~/tmp/isspst/signedDoc

@ -38,8 +38,14 @@
<menuseparator/>
<menuitem
image="/img/invoicing-016.png"
label="${labels.Invoicing}"
href="/main/invoicing/"
label="${labels.InvoicingMaterial}"
href="/main/invoicing/material/"
disabled="${not sec:isAllGranted('PERM_READ_INVOICING')}"
visible="${module:isActive('INVOICING') }" />
<menuitem
image="/img/invoicing-016.png"
label="${labels.InvoicingServices}"
href="/main/invoicing/services/"
disabled="${not sec:isAllGranted('PERM_READ_INVOICING')}"
visible="${module:isActive('INVOICING') }" />
</menupopup>

@ -1,215 +0,0 @@
<?page contentType="text/html;charset=UTF-8"?>
<zk>
<window
id="editWin"
closable="true"
width="95%"
height="95%"
border="normal"
position="center"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingForm')">
<caption
src="/img/invoicing-032.png"
zclass="form-caption"
label="${labels.InvoicingFormTitle}" />
<vlayout vflex="1">
<hbox
vflex="min"
hflex="1">
<div hflex="1">
<button
image="/img/item-add.png"
label="${labels.InvoicingAdd}"
sclass="nicebutton"
onClick="@command('addItem')" />
</div>
<div hflex="1"></div>
<div
hflex="1"
align="right">
<checkbox
label="${labels.Completed}"
checked="@bind(vm.dataBean.completed)" />
</div>
</hbox>
<hbox vflex="1">
<vbox vflex="1">
<listbox
model="@load(vm.dataBean.items)"
vflex="1"
selectedItem="@bind(vm.selectedItem)"
selectedIndex="@bind(vm.selectedIndex)">
<listhead>
<listheader
label="${labels.InvoicingDate}"
width="150px" />
<listheader label="${labels.InvoicingInvoiceNumber}" />
<listheader
label="${labels.InvoicingAmount}"
align="right"
width="90px" />
<listheader />
</listhead>
<template name="model">
<listitem>
<listcell>
<datebox
value="@bind(each.invoiceDate)"
format="${labels.DateFormat}"
inplace="true"
onFocus="@command('onFocus', item=each)" />
</listcell>
<listcell>
<textbox
value="@bind(each.invoiceNumber)"
sclass="grid-textbox-max"
inplace="true"
maxlength="@load(vm.lengthText)"
onFocus="@command('onFocus', item=each)" />
</listcell>
<listcell>
<textbox
value="@bind(each.amount) @converter(vm.standardBigDecimalConverter)"
sclass="grid-textbox-max"
inplace="true"
onFocus="@command('onFocus', item=each)"
maxlength="@load(vm.lengthText)"
onChange="@command('calculate')" />
</listcell>
<listcell>
<button
label="${labels.RemoveItem}"
sclass="nicebutton"
onClick="@command('removeItem', item=each)" />
</listcell>
</listitem>
</template>
</listbox>
</vbox>
<grid hflex="min">
<columns>
<column
align="right"
hflex="min" />
<column />
</columns>
<rows>
<row>
<cell sclass="row-title">${labels.InvoicingRequirementNumber} :</cell>
<cell>
<textbox
width="200px"
value="@bind(vm.dataBean.requirement.numser)"
style="font-weight: bold;"
maxlength="@load(vm.lengthText)"
readonly="true" />
</cell>
</row>
<row>
<cell sclass="row-title">${labels.InvoicingDescription} :</cell>
<cell>
<textbox
width="350px"
rows="5"
value="@bind(vm.dataBean.requirement.description)"
maxlength="@load(vm.lengthDescription)"
readonly="true" />
</cell>
</row>
<row>
<cell sclass="row-title">${labels.InvoicingRequirementPrice} :</cell>
<cell>
<textbox
width="150px"
value="@bind(vm.dataBean.requirement.sumTotal) @converter(vm.standardBigDecimalConverter)"
maxlength="@load(vm.lengthText)"
readonly="true" />
</cell>
</row>
<row>
<cell sclass="row-title">${labels.InvoicingInvoicedPrice} :</cell>
<cell>
<textbox
width="150px"
value="@bind(vm.dataBean.totalInvoiced) @converter(vm.standardBigDecimalConverter)"
readonly="true"
maxlength="@load(vm.lengthText)"
style="@load(vm.dataBean.totalInvoiced gt vm.dataBean.requirement.sumTotal ? ' color: red;' : '' )" />
</cell>
</row>
</rows>
</grid>
</hbox>
<listbox
vflex="1"
model="@load(vm.dataBean.requirement.items)">
<listhead>
<listheader
hflex="10"
label="${labels.RequirementItemCode}" />
<listheader
hflex="15"
label="${labels.RequirementItemName}" />
<listheader
hflex="30"
label="${labels.RequirementItemText}" />
<listheader
hflex="10"
align="right"
label="${labels.RequirementItemQuantity}" />
<listheader
hflex="10"
label="${labels.RequirementItemMUnit}" />
<listheader
hflex="10"
align="right"
label="${labels.RequirementItemUnitPrice}" />
<listheader
hflex="10"
align="right"
label="${labels.RequirementItemTotal}" />
<listheader
hflex="10"
align="right"
label="${labels.InvoicingInvoiced}" />
<listheader
hflex="15"
label="${labels.RequirementItemDescription}" />
</listhead>
<template name="model">
<listitem>
<listcell>
<label value="@load(each.code)" />
</listcell>
<listcell>
<label value="@load(each.name)" />
</listcell>
<listcell>
<label value="@load(each.textItem)" />
</listcell>
<listcell>
<label value="@bind(each.quantity) @converter(vm.standardBigDecimalConverter)" />
</listcell>
<listcell>
<label value="@bind(each.munit.name)" />
</listcell>
<listcell>
<label value="@bind(each.unitPrice) @converter(vm.standardBigDecimalConverter)" />
</listcell>
<listcell>
<label value="@bind(each.total) @converter(vm.standardBigDecimalConverter)" />
</listcell>
<listcell>
<checkbox checked="@bind(each.paid)" />
</listcell>
<listcell>
<label value="@bind(each.description)" />
</listcell>
</listitem>
</template>
</listbox>
<include src="/app/formButtons.zul" />
</vlayout>
</window>
</zk>

@ -1,4 +1,4 @@
<?page title="${labels.Invoicing}" contentType="text/html;charset=UTF-8"?>
<?page title="${labels.InvoicingMaterial}" contentType="text/html;charset=UTF-8"?>
<zk>
<zscript>

@ -0,0 +1,20 @@
<?page title="${labels.InvoicingMaterial}" contentType="text/html;charset=UTF-8"?>
<zk>
<window
id="editWin"
width="95%"
height="95%"
closable="true"
border="normal"
position="center"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingForm')">
<caption
image="/img/invoicing-032.png"
zclass="form-caption"
label="${labels.InvoicingMaterial}" />
<include
vflex="1"
src="/main/invoicing/shared/invoicingForm.zul" />
</window>
</zk>

@ -4,10 +4,10 @@
vflex="1"
border="none"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingArchiveList')">
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingMaterialArchiveList')">
<include src="/app/toolbar.zul" />
<include
vflex="1"
src="/main/invoicing/invoicingGrid.zul" />
src="/main/invoicing/shared/invoicingGrid.zul" />
</window>
</zk>

@ -4,10 +4,10 @@
vflex="1"
border="none"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingPendingList')">
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingMaterialPendingList')">
<include src="/app/toolbar.zul" />
<include
vflex="1"
src="/main/invoicing/invoicingGrid.zul" />
src="/main/invoicing/shared/invoicingGrid.zul" />
</window>
</zk>

@ -2,8 +2,8 @@
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<zk>
<zscript>
String gridPending = "/main/invoicing/invHeadListPending.zul";
String gridArchive = "/main/invoicing/invHeadListArchive.zul";
String gridPending = "/main/invoicing/material/invHeadListPending.zul";
String gridArchive = "/main/invoicing/material/invHeadListArchive.zul";
</zscript>
<window
vflex="1"
@ -11,9 +11,9 @@
<caption
src="/img/invoicing-032.png"
zclass="form-caption"
label="${labels.Invoicing}" />
label="${labels.InvoicingMaterial}" />
<include
vflex="1"
src="/main/invoicing/tabPanels.zul" />
src="/main/invoicing/shared/tabPanels.zul" />
</window>
</zk>

@ -0,0 +1,10 @@
<?page title="${labels.InvoicingServices}" contentType="text/html;charset=UTF-8"?>
<zk>
<zscript>
String gridZul = "setup.zul";
</zscript>
<include src="/app/template.zhtml"/>
</zk>

@ -0,0 +1,20 @@
<?page title="${labels.InvoicingServices}" contentType="text/html;charset=UTF-8"?>
<zk>
<window
id="editWin"
width="95%"
height="95%"
closable="true"
border="normal"
position="center"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingForm')">
<caption
image="/img/invoicing-032.png"
zclass="form-caption"
label="${labels.InvoicingServices}" />
<include
vflex="1"
src="/main/invoicing/shared/invoicingForm.zul" />
</window>
</zk>

@ -0,0 +1,13 @@
<zk>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<window
vflex="1"
border="none"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingServicesArchiveList')">
<include src="/app/toolbar.zul" />
<include
vflex="1"
src="/main/invoicing/shared/invoicingGrid.zul" />
</window>
</zk>

@ -0,0 +1,13 @@
<zk>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<window
vflex="1"
border="none"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.main.invoicing.InvoicingServicesPendingList')">
<include src="/app/toolbar.zul" />
<include
vflex="1"
src="/main/invoicing/shared/invoicingGrid.zul" />
</window>
</zk>

@ -0,0 +1,19 @@
<?page contentType="text/html;charset=UTF-8"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<zk>
<zscript>
String gridPending = "/main/invoicing/services/invHeadListPending.zul";
String gridArchive = "/main/invoicing/services/invHeadListArchive.zul";
</zscript>
<window
vflex="1"
border="normal">
<caption
src="/img/invoicing-032.png"
zclass="form-caption"
label="${labels.InvoicingServices}" />
<include
vflex="1"
src="/main/invoicing/shared/tabPanels.zul" />
</window>
</zk>

@ -0,0 +1,198 @@
<vlayout vflex="1">
<hbox
vflex="min"
hflex="1">
<div hflex="1">
<button
image="/img/item-add.png"
label="${labels.InvoicingAdd}"
sclass="nicebutton"
onClick="@command('addItem')"/>
</div>
<div hflex="1"></div>
<div
hflex="1"
align="right">
<checkbox
label="${labels.Completed}"
checked="@bind(vm.dataBean.completed)"/>
</div>
</hbox>
<hbox vflex="1">
<vbox vflex="1">
<listbox
model="@load(vm.dataBean.items)"
vflex="1"
selectedItem="@bind(vm.selectedItem)"
selectedIndex="@bind(vm.selectedIndex)">
<listhead>
<listheader
label="${labels.InvoicingDate}"
width="150px"/>
<listheader label="${labels.InvoicingInvoiceNumber}"/>
<listheader
label="${labels.InvoicingAmount}"
align="right"
width="90px"/>
<listheader/>
</listhead>
<template name="model">
<listitem>
<listcell>
<datebox
value="@bind(each.invoiceDate)"
format="${labels.DateFormat}"
inplace="true"
onFocus="@command('onFocus', item=each)"/>
</listcell>
<listcell>
<textbox
value="@bind(each.invoiceNumber)"
sclass="grid-textbox-max"
inplace="true"
maxlength="@load(vm.lengthText)"
onFocus="@command('onFocus', item=each)"/>
</listcell>
<listcell>
<textbox
value="@bind(each.amount) @converter(vm.standardBigDecimalConverter)"
sclass="grid-textbox-max"
inplace="true"
onFocus="@command('onFocus', item=each)"
maxlength="@load(vm.lengthText)"
onChange="@command('calculate')"/>
</listcell>
<listcell>
<button
label="${labels.RemoveItem}"
sclass="nicebutton"
onClick="@command('removeItem', item=each)"/>
</listcell>
</listitem>
</template>
</listbox>
</vbox>
<grid hflex="min">
<columns>
<column
align="right"
hflex="min"/>
<column/>
</columns>
<rows>
<row>
<cell sclass="row-title">${labels.InvoicingRequirementNumber} :</cell>
<cell>
<textbox
width="200px"
value="@bind(vm.dataBean.requirement.numser)"
style="font-weight: bold;"
maxlength="@load(vm.lengthText)"
readonly="true"/>
</cell>
</row>
<row>
<cell sclass="row-title">${labels.InvoicingDescription} :</cell>
<cell>
<textbox
width="350px"
rows="5"
value="@bind(vm.dataBean.requirement.description)"
maxlength="@load(vm.lengthDescription)"
readonly="true"/>
</cell>
</row>
<row>
<cell sclass="row-title">${labels.InvoicingRequirementPrice} :</cell>
<cell>
<textbox
width="150px"
value="@bind(vm.dataBean.requirement.sumTotal) @converter(vm.standardBigDecimalConverter)"
maxlength="@load(vm.lengthText)"
readonly="true"/>
</cell>
</row>
<row>
<cell sclass="row-title">${labels.InvoicingInvoicedPrice} :</cell>
<cell>
<textbox
width="150px"
value="@bind(vm.dataBean.totalInvoiced) @converter(vm.standardBigDecimalConverter)"
readonly="true"
maxlength="@load(vm.lengthText)"
style="@load(vm.dataBean.totalInvoiced gt vm.dataBean.requirement.sumTotal ? ' color: red;' : '' )"/>
</cell>
</row>
</rows>
</grid>
</hbox>
<listbox
vflex="1"
model="@load(vm.dataBean.requirement.items)">
<listhead>
<listheader
hflex="10"
label="${labels.RequirementItemCode}"/>
<listheader
hflex="15"
label="${labels.RequirementItemName}"/>
<listheader
hflex="30"
label="${labels.RequirementItemText}"/>
<listheader
hflex="10"
align="right"
label="${labels.RequirementItemQuantity}"/>
<listheader
hflex="10"
label="${labels.RequirementItemMUnit}"/>
<listheader
hflex="10"
align="right"
label="${labels.RequirementItemUnitPrice}"/>
<listheader
hflex="10"
align="right"
label="${labels.RequirementItemTotal}"/>
<listheader
hflex="10"
align="right"
label="${labels.InvoicingInvoiced}"/>
<listheader
hflex="15"
label="${labels.RequirementItemDescription}"/>
</listhead>
<template name="model">
<listitem>
<listcell>
<label value="@load(each.code)"/>
</listcell>
<listcell>
<label value="@load(each.name)"/>
</listcell>
<listcell>
<label value="@load(each.textItem)"/>
</listcell>
<listcell>
<label value="@bind(each.quantity) @converter(vm.standardBigDecimalConverter)"/>
</listcell>
<listcell>
<label value="@bind(each.munit.name)"/>
</listcell>
<listcell>
<label value="@bind(each.unitPrice) @converter(vm.standardBigDecimalConverter)"/>
</listcell>
<listcell>
<label value="@bind(each.total) @converter(vm.standardBigDecimalConverter)"/>
</listcell>
<listcell>
<checkbox checked="@bind(each.paid)"/>
</listcell>
<listcell>
<label value="@bind(each.description)"/>
</listcell>
</listitem>
</template>
</listbox>
<include src="/app/formButtons.zul"/>
</vlayout>
Loading…
Cancel
Save