<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
- %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
+ %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.} \(%line\)): %msg%n%throwable
</Pattern>
</layout>
</appender>
--- /dev/null
+-- // add price exchange fields to invoice
+-- Migration SQL that makes the change goes here.
+
+ALTER TABLE invoice
+ ADD COLUMN net_amount_huf DOUBLE
+ ADD COLUMN gross_amount_huf DOUBLE
+ ADD COLUMN exchange_rate DOUBLE;
+
+-- //@UNDO
+-- SQL to undo the change goes here.
+
+ALTER TABLE invoice
+ DROP COLUMN net_amount_huf
+ DROP COLUMN gross_amount_huf
+ DROP COLUMN exchange_rate;
+CALL SYSPROC.ADMIN_CMD('REORG TABLE invoice');
--- /dev/null
+-- // add price exchange fields to treasury
+-- Migration SQL that makes the change goes here.
+
+ALTER TABLE treasury
+ ADD COLUMN buy_amount_huf DOUBLE
+ ADD COLUMN buy_exchange_rate DOUBLE
+ ADD COLUMN sell_amount_huf DOUBLE
+ ADD COLUMN sell_exchange_rate DOUBLE;
+
+-- //@UNDO
+-- SQL to undo the change goes here.
+
+ALTER TABLE treasury
+ DROP COLUMN buy_amount_huf
+ DROP COLUMN buy_exchange_rate
+ DROP COLUMN sell_amount_huf
+ DROP COLUMN sell_exchange_rate;
+CALL SYSPROC.ADMIN_CMD('REORG TABLE treasury');
import lombok.Setter;
import lombok.experimental.SuperBuilder;
-import javax.persistence.*;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
import java.util.Date;
@Getter
private double vatAmount;
+ @Column(name = "net_amount_huf")
+ private Double netAmountHUF;
+
+ @Column(name = "gross_amount_huf")
+ private Double grossAmountHUF;
+
+ private Double exchangeRate;
+
private Date completionDate;
private Date createDate;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
+import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
private double buyAmount;
+ @Column(name = "buy_amount_huf")
+ private Double buyAmountHUF;
+
+ private Double buyExchangeRate;
+
private Currency buyCurrency;
private double sellAmount;
+ @Column(name = "sell_amount_huf")
+ private Double sellAmountHUF;
+
+ private Double sellExchangeRate;
+
private Currency sellCurrency;
private Date transactionDate;
+++ /dev/null
-package hu.user.lis.ui.data;
-
-import hu.user.lis.db.Currency;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-@Builder
-public class
-IncomeMargin {
- Currency currency;
- Double amount;
-}
package hu.user.lis.ui.data;
import hu.user.lis.db.Currency;
-import hu.user.lis.db.*;
+import hu.user.lis.db.IncomingInvoice;
+import hu.user.lis.db.Invoice;
+import hu.user.lis.db.OutgoingInvoice;
+import hu.user.lis.db.Project;
+import hu.user.lis.db.ServiceRecord;
+import hu.user.lis.db.Treasury;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkoss.bind.BindUtils;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
@Component
@Log4j2
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class IncomeMarginsDataModel extends ArrayList<IncomeMargin> {
- public void recalculate(Project project, ServiceRecordsDataModel serviceRecordsDataModel) {
+public class IncomeMarginsDataModel extends ArrayList<MoneyAmount> {
+ public void recalculate(Project project, ServiceRecordsDataModel serviceRecordsDataModel) throws Exception {
clear();
- Map<Currency, Double> balances = new HashMap<>();
+ Map<Currency, MoneyAmount> balances = new HashMap<>();
List<OutgoingInvoice> outgoingInvoices = project.getOutgoingInvoices();
if (Objects.nonNull(outgoingInvoices)) {
for (Invoice invoice : outgoingInvoices) {
- addBalance(balances, invoice.getCurrency(), invoice.getNetAmount());
+ addBalance(balances, MoneyAmount.fromInvoice(invoice));
}
}
List<IncomingInvoice> incomingInvoices = project.getIncomingInvoices();
if (Objects.nonNull(incomingInvoices)) {
for (Invoice invoice : incomingInvoices) {
- substractBalance(balances, invoice.getCurrency(), invoice.getNetAmount());
+ subtractBalance(balances, MoneyAmount.fromInvoice(invoice));
}
}
List<Treasury> treasuries = project.getTreasuries();
if (Objects.nonNull(treasuries)) {
for (Treasury treasury : treasuries) {
- substractBalance(balances, treasury.getSellCurrency(), treasury.getSellAmount());
- addBalance(balances, treasury.getBuyCurrency(), treasury.getBuyAmount());
+ subtractBalance(balances, MoneyAmount.fromTreasuryBuy(treasury));
+ addBalance(balances, MoneyAmount.fromTreasurySell(treasury));
}
}
-
for (int i = 0; i < serviceRecordsDataModel.getSize(); i++) {
ServiceRecord serviceRecord = serviceRecordsDataModel.getElementAt(i);
- substractBalance(balances, Currency.HUF, serviceRecord.getCost());
+ subtractBalance(balances, MoneyAmount.fromServiceRecord(serviceRecord));
}
- balances.entrySet().stream()
- .map(s -> IncomeMargin.builder().currency(s.getKey()).amount(s.getValue()).build())
- .sorted(Comparator.comparing(IncomeMargin::getCurrency))
- .collect(Collectors.toCollection(() -> this));
-
+ balances.keySet().stream().sorted().forEach(currency -> this.add(balances.get(currency)));
BindUtils.postNotifyChange(this, "*");
}
- private void addBalance(Map<Currency, Double> balances, Currency currency, double amount) {
- double currentBalance = balances.containsKey(currency) ? balances.get(currency) : 0;
- currentBalance += amount;
- balances.put(currency, currentBalance);
+ private void addBalance(Map<Currency, MoneyAmount> balances, MoneyAmount moneyAmount) throws Exception {
+ MoneyAmount currentBalance = balances.containsKey(moneyAmount.getCurrency()) ?
+ balances.get(moneyAmount.getCurrency()) :
+ MoneyAmount.builder().currency(moneyAmount.getCurrency()).build();
+ currentBalance.add(moneyAmount);
+ balances.put(moneyAmount.getCurrency(), currentBalance);
}
- private void substractBalance(Map<Currency, Double> balances, Currency currency, double amount) {
- double currentBalance = balances.containsKey(currency) ? balances.get(currency) : 0;
- currentBalance -= amount;
- balances.put(currency, currentBalance);
+ private void subtractBalance(Map<Currency, MoneyAmount> balances, MoneyAmount moneyAmount) throws Exception {
+ MoneyAmount currentBalance = balances.containsKey(moneyAmount.getCurrency()) ?
+ balances.get(moneyAmount.getCurrency()) :
+ MoneyAmount.builder().currency(moneyAmount.getCurrency()).build();
+ currentBalance.subtract(moneyAmount);
+ balances.put(moneyAmount.getCurrency(), currentBalance);
}
}
--- /dev/null
+package hu.user.lis.ui.data;
+
+import hu.user.lis.db.Currency;
+import hu.user.lis.db.Invoice;
+import hu.user.lis.db.ServiceRecord;
+import hu.user.lis.db.Treasury;
+import hu.user.lis.db.Vat;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Objects;
+
+@Getter
+@Setter
+@Builder
+public class MoneyAmount {
+ Currency currency;
+
+ @Builder.Default
+ Double netAmount = (double) 0;
+ @Builder.Default
+ Double grossAmount = (double) 0;
+ @Builder.Default
+ Double netAmountHUF = (double) 0;
+ @Builder.Default
+ Double grossAmountHUF = (double) 0;
+ @Builder.Default
+ Double exchangeRate = (double) 0;
+
+ public void add(MoneyAmount money) throws Exception {
+ if (!money.getCurrency().equals(currency)) {
+ throw new Exception("Can't add different currencies");
+ }
+ if (Objects.nonNull(money.getNetAmount())) {
+ netAmount += money.getNetAmount();
+ }
+ if (Objects.nonNull(money.getGrossAmount())) {
+ grossAmount += money.getGrossAmount();
+ }
+ if (Objects.nonNull(money.getNetAmountHUF())) {
+ netAmountHUF += money.getNetAmountHUF();
+ }
+ if (Objects.nonNull(money.getGrossAmountHUF())) {
+ grossAmountHUF += money.getGrossAmountHUF();
+ }
+ }
+
+ public void subtract(MoneyAmount money) throws Exception {
+ if (!money.getCurrency().equals(currency)) {
+ throw new Exception("Can't subtract different currencies");
+ }
+ if (Objects.nonNull(money.getNetAmount())) {
+ netAmount -= money.getNetAmount();
+ }
+ if (Objects.nonNull(money.getGrossAmount())) {
+ grossAmount -= money.getGrossAmount();
+ }
+ if (Objects.nonNull(money.getNetAmountHUF())) {
+ netAmountHUF -= money.getNetAmountHUF();
+ }
+ if (Objects.nonNull(money.getGrossAmountHUF())) {
+ grossAmountHUF -= money.getGrossAmountHUF();
+ }
+ }
+
+ public static MoneyAmount fromInvoice(Invoice invoice) {
+ return MoneyAmount.builder()
+ .currency(invoice.getCurrency())
+ .netAmount(invoice.getNetAmount())
+ .grossAmount(invoice.getGrossAmount())
+ .netAmountHUF(invoice.getNetAmountHUF())
+ .grossAmountHUF(invoice.getGrossAmountHUF())
+ .exchangeRate(invoice.getExchangeRate())
+ .build();
+ }
+
+ public static MoneyAmount fromTreasuryBuy(Treasury treasury) {
+ return MoneyAmount.builder()
+ .currency(treasury.getBuyCurrency())
+ .netAmount(treasury.getBuyAmount())
+ .grossAmount(treasury.getBuyAmount())
+ .netAmountHUF(treasury.getBuyAmountHUF())
+ .build();
+
+ }
+
+ public static MoneyAmount fromTreasurySell(Treasury treasury) {
+ return MoneyAmount.builder()
+ .currency(treasury.getSellCurrency())
+ .netAmount(treasury.getSellAmount())
+ .grossAmount(treasury.getSellAmount())
+ .netAmountHUF(treasury.getSellAmountHUF())
+ .build();
+ }
+
+ public static MoneyAmount fromServiceRecord(ServiceRecord serviceRecord) {
+ Vat monthlyVat = serviceRecord.getAssociate().getMonthlyVat();
+ float vatPercent = monthlyVat.getVal();
+ double grossAmount = serviceRecord.getCost();
+ if (monthlyVat != Vat.PERCENT_0) {
+ grossAmount += vatPercent * serviceRecord.getCost() / 100;
+ }
+
+ return MoneyAmount.builder()
+ .currency(Currency.HUF)
+ .netAmount(serviceRecord.getCost())
+ .grossAmount(grossAmount)
+ .netAmountHUF(serviceRecord.getCost())
+ .grossAmountHUF(grossAmount)
+ .exchangeRate((double) 1)
+ .build();
+
+ }
+}
package hu.user.lis.ui.editor;
import com.google.common.collect.ImmutableMap;
-import hu.user.lis.db.*;
+import hu.user.lis.db.Associate;
+import hu.user.lis.db.IncomingInvoice;
+import hu.user.lis.db.Invoice;
+import hu.user.lis.db.OutgoingInvoice;
+import hu.user.lis.db.Partner;
+import hu.user.lis.db.Project;
+import hu.user.lis.db.ProjectAssociate;
+import hu.user.lis.db.Treasury;
import hu.user.lis.db.repository.InvoiceRepository;
import hu.user.lis.service.data.EntityDocumentAction;
import hu.user.lis.service.data.EntityDocumentService;
import hu.user.lis.ui.Constants;
import hu.user.lis.ui.converter.ProjectStatusConverter;
-import hu.user.lis.ui.data.*;
+import hu.user.lis.ui.data.AssociatesDataModel;
+import hu.user.lis.ui.data.IncomeMarginsDataModel;
+import hu.user.lis.ui.data.InvoiceDataModel;
+import hu.user.lis.ui.data.ProjectAssociatesDataModel;
+import hu.user.lis.ui.data.ProjectStatusDataModel;
+import hu.user.lis.ui.data.ProjectsDataModel;
+import hu.user.lis.ui.data.ServiceRecordsDataModel;
+import hu.user.lis.ui.data.TreasuryDataModel;
import hu.user.lis.ui.editor.common.Editors;
import hu.user.lis.ui.editor.common.EntityEditorModel;
import hu.user.lis.ui.editor.validator.FormValidator;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.bind.BindUtils;
-import org.zkoss.bind.annotation.*;
+import org.zkoss.bind.annotation.BindingParam;
+import org.zkoss.bind.annotation.Command;
+import org.zkoss.bind.annotation.Destroy;
+import org.zkoss.bind.annotation.Init;
+import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.select.annotation.WireVariable;
initAssociates();
serviceRecordsDataModel.search(getFormDocument(), true);
getEntitySelectorRouter().configureSelector(Partner.class, getFormDocument(), "partner");
- incomeMarginsDataModel.recalculate(getFormDocument(), serviceRecordsDataModel);
+ safeRecalcMargin();
}
@Override
public void validate() {
super.validate();
- incomeMarginsDataModel.recalculate(getFormDocument(), serviceRecordsDataModel);
+ safeRecalcMargin();
}
+ private void safeRecalcMargin() {
+ try {
+ incomeMarginsDataModel.recalculate(getFormDocument(), serviceRecordsDataModel);
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ }
+ }
+
+
}
<tabpanels>
<tabpanel>
<vlayout vflex="true">
+ <window title="Árrés (HUF)">
+ <hbox>
+ <panel title="Bevétel">
+ <panelchildren>
+ <label value="@load(vm.formDocument.supplyPrice)"/>
+ </panelchildren>
+ </panel>
+ <panel title="Kiadás">
+ <panelchildren>
+ <label value="@load(vm.formDocument.sellingPrice)"/>
+ </panelchildren>
+ </panel>
+ <panel title="Árrés">
+ <panelchildren>
+ <label value="@load(vm.formDocument.margin)"/>
+ </panelchildren>
+ </panel>
+ </hbox>
+ </window>
<grid sclass="no-hover-grid" oddRowSclass="none"
model="@load(vm.incomeMarginsDataModel)"
forward="onOK=submit.onClick, onCancel=cancel.onClick"
emptyMessage="Nem kalkulálható!">
<columns visible="false">
<column width="50px" label="Pénznem"/>
- <column width="100%" label="Összeg"/>
+ <column width="100%" label="Nettó összeg"/>
+ <column width="100%" label="Bruttó összeg"/>
</columns>
<rows>
<template name="model">
<row>
<label value="@load(each.currency)"/>
- <label value="@load(each.amount) @converter('hu.user.lis.ui.converter.DoubleToStringConverter')"/>
+ <label value="@load(each.netAmount) @converter('hu.user.lis.ui.converter.DoubleToStringConverter')"/>
+ <label value="@load(each.grossAmount) @converter('hu.user.lis.ui.converter.DoubleToStringConverter')"/>
</row>
</template>
</rows>
</grid>
-
</vlayout>
</tabpanel>
</tabpanels>