18 package org.turro.financials.entity;
20 import java.text.SimpleDateFormat;
22 import javax.persistence.*;
23 import org.amic.util.date.CheckDate;
24 import org.turro.string.Strings;
25 import org.turro.contacts.Contact;
26 import org.turro.contacts.util.ContactList;
27 import org.turro.elephant.db.IdUtils;
28 import org.turro.entities.Entities;
29 import org.turro.entities.IElephantEntity;
30 import org.turro.financials.db.FinancialsPU;
31 import org.turro.financials.model.RelatedToLineTypeAdapter;
32 import org.turro.financials.model.contract.ContractWrapper;
33 import org.turro.financials.model.document.AmountTaxable;
34 import org.turro.financials.model.document.DocumentAmounts;
35 import org.turro.financials.model.document.DocumentAmountsByBook;
36 import org.turro.financials.model.document.DocumentDefinitionWrapper;
37 import org.turro.financials.model.document.DocumentLineComparator;
38 import org.turro.financials.model.document.LineTypeSet;
39 import org.turro.html.HtmlContent;
40 import org.turro.jpa.Dao;
41 import org.turro.jpa.entity.IDaoEntity;
42 import org.turro.mail.message.MailUtils;
43 import org.turro.plugin.scheduler.ScheduledAction;
44 import org.turro.reflection.MappingSet;
45 import org.turro.util.Chars;
46 import org.turro.util.PhraseBuilder;
54 @Index(name=
"IndexDocument", columnList=
"documentNumber,documentDate")
59 @GeneratedValue(strategy=GenerationType.IDENTITY)
60 @Column(name=
"IDENTIFIER")
63 @ManyToOne(fetch=FetchType.LAZY)
73 @Temporal(value = TemporalType.DATE)
74 private Date receiptDate;
76 @Column(nullable=false)
77 @Temporal(value = TemporalType.DATE)
78 private Date documentDate;
80 @Column(nullable=false)
81 private String documentNumber;
83 private Currency currency;
87 private
boolean draft, noAncestors = false, noDescendants = false;
89 private String relatedPath;
94 @OneToMany(mappedBy = "descendant", fetch = FetchType.EAGER)
97 @OneToMany(mappedBy = "ancestor", fetch = FetchType.EAGER)
100 @OneToMany(mappedBy = "document", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)
101 private Set<
Register> registers = new HashSet<>();
103 @OneToMany(mappedBy = "document", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)
104 @OrderBy(value="lineOrder")
110 ancestors = dao.lazyLoader(
Document.class,
this,
"ancestors").ancestors;
116 this.ancestors = ancestors;
124 this.contract = contract;
129 if(currency ==
null && contract !=
null) {
130 currency = contract.getCurrency();
136 this.currency = currency;
142 descendants = dao.lazyLoader(
Document.class,
this,
"descendants").descendants;
150 descendants = dao.lazyLoader(
Document.class,
this,
"descendants").descendants;
156 this.descendants = descendants;
164 this.documentDate = documentDate;
169 if(
id > 0 && dao.
isNotLoaded(documentDefinition)) {
170 setDocumentDefinition(dao.lazyLoader(
Document.class,
this,
"documentDefinition").documentDefinition);
172 return documentDefinition;
176 this.documentDefinition = documentDefinition;
181 return documentLines;
185 this.documentLines = documentLines;
189 return documentNumber;
193 this.documentNumber = documentNumber;
209 this.forcedView = forcedView;
225 this.noAncestors = noAncestors;
229 return noDescendants;
233 this.noDescendants = noDescendants;
257 this.receiptDate = receiptDate;
265 this.registers = registers;
273 this.relatedPath = relatedPath;
285 return documentLines.isEmpty() ||
288 documentDate ==
null ||
295 if(Strings.isBlank(documentNumber)) {
300 if(forcedView ==
null) {
304 "year(receiptDate) = " +
new CheckDate(receiptDate).getYear(),
305 "documentDefinition_identifier = " + getDocumentDefinition().getId(),
306 "forcedView_identifier is null"
312 "year(receiptDate) = " +
new CheckDate(receiptDate).getYear(),
313 "documentDefinition_identifier = " + getDocumentDefinition().getId(),
314 "forcedView_identifier = " + forcedView.getId()
323 return List.of(getRegisters());
333 return !(contract ==
null || getDocumentDefinition() ==
null);
337 Iterator<DocumentLine> itl = getDocumentLines().iterator();
338 while(itl.hasNext()) {
339 if(!itl.next().isEmpty()) {
347 PhraseBuilder pb =
new PhraseBuilder();
349 pb.addWord(dl.getConcept());
351 return pb.toString();
359 PhraseBuilder pb =
new PhraseBuilder();
363 pb.addPendingSeparator(Chars.nl().repeat(2).toString());
365 if(cdNotes !=
null) {
368 return pb.toString();
372 Iterator<DocumentLine> itl = getDocumentLines().iterator();
373 while(itl.hasNext()) {
374 if(itl.next().isEmpty()) {
381 Iterator<DocumentLine> it = lines.iterator();
383 while(it.hasNext()) {
384 it.next().setLineOrder(c++);
422 return getAmounts().getAmount();
426 return getAmounts().getTotal();
430 if(getContract() !=
null) {
431 if(getContract().getContractPreferences().isEmpty()) {
434 return getContract().getContractPreferences().iterator().next();
441 int count = getMaxLineOrder() + 1;
443 Contract defaultStore = getDefaultStore();
449 documentLines.add(dl);
466 if(l.getLineType() !=
null) {
467 double sc = l.getLineType().getStockCoefficient();
470 for(
RelatedLineType rlt : getDocumentDefinition().getRelatedLineTypes()) {
471 if((sc == 0 && rlt.getLineType().getStockCoefficient() != 0) ||
472 (sc != 0 && rlt.getLineType().getStockCoefficient() == 0)) {
484 if(workflow ==
null) {
489 documentLines.add(dl);
494 int count = getMaxLineOrder() + 1;
497 for(
RelatedLineType rlt : getDocumentDefinition().getRelatedLineTypes()) {
498 if(rlt.getLineType().getStockCoefficient() == 0) {
499 lt = rlt.getLineType();
505 lt = getDefaultLineType();
507 Contract defaultStore = getDefaultStore();
513 dl.
setConcept(header +
" [" + l.getTax() +
"]");
522 documentLines.add(dl);
535 documentLines.add(dl);
540 Date now =
new Date();
543 setDocumentDate(now);
544 setDocumentNumber(
null);
550 appendLines(doc, header, workflow);
552 appendAmounts(doc, header, workflow);
557 getAncestors().add(dr);
561 Date now =
new Date();
564 setDocumentDate(now);
565 setDocumentNumber(
null);
571 appendLines(doc, header,
null);
573 appendAmounts(doc, header,
null);
578 getDescendants().add(dr);
593 Contract defaultStore = (!shallowCopy) ?
null : getDefaultStore();
607 nl.
setStore(shallowCopy ? defaultStore : dl.getStore());
611 documentLines.add(nl);
616 return contract ==
null ? null : contract.getFlowFor(
this);
620 return getWorkflows(
true,
true);
623 public Collection<DocumentWorkflow>
getWorkflows(
boolean forward,
boolean missing) {
624 if(forward && (!missing || getDescendants().isEmpty())) {
626 "select dw from DocumentWorkflow as dw " +
627 "where dw.ancestor = ? " +
628 "and dw.contractDefinition = ?",
630 getDocumentDefinition(),
631 contract.getContractDefinition()
633 }
else if(!forward && (!missing || getAncestors().isEmpty())) {
635 "select dw from DocumentWorkflow as dw " +
636 "where dw.descendant = ? " +
637 "and dw.contractDefinition = ?",
639 getDocumentDefinition(),
640 contract.getContractDefinition()
643 return Collections.EMPTY_LIST;
649 if(!line.isEmpty()) {
660 return getDocumentDefinition().getName() +
": " +
661 (getForcedView() ==
null ?
"" :
"(" + getForcedView().getName() +
") ") +
662 getDocumentNumber() +
" " +
663 SimpleDateFormat.getDateInstance().format(documentDate);
667 return getDocumentDefinition().getName() +
" " + documentNumber +
" " +
668 SimpleDateFormat.getDateInstance().format(documentDate);
674 private transient Collection<Contract> _stores;
677 if(_stores ==
null) {
680 if(_stores.isEmpty()) {
690 Collection<Contract> stores = getStores();
691 if(!stores.isEmpty()) {
692 return stores.iterator().next();
700 if(dl.getLineOrder() > result) {
701 result = dl.getLineOrder();
709 if(contract !=
null && getDocumentDefinition() !=
null) {
710 return contract.getUsualPath(getDocumentDefinition());
719 if(getDocumentDefinition() !=
null) {
720 for(
RelatedLineType rlt : getDocumentDefinition().getRelatedLineTypes()) {
721 if(rlt.isDefaultLineType()) {
723 if(rlt.getLineType().getId() == l.getId()) {
726 if(lt ==
null) lt = l;
736 if(getDocumentDefinition() !=
null && contract !=
null) {
739 if(lt.getName().contains(
"%n")) {
740 if(contract.getContractPreferences().isEmpty()) {
765 if(data.contains(
"action:clone")) {
773 nd.
setDraft(data.contains(
"clone:draft"));
783 if(!getRegisters().isEmpty()) {
784 Register register = getRegisters().iterator().next();
785 if(!
register.getBookRegisters().isEmpty()) {
798 return conciliateRegister;
802 this.conciliateRegister = conciliateRegister;
809 return regularizeVAT;
813 this.regularizeVAT = regularizeVAT;
820 return regularizeIRPF;
824 this.regularizeIRPF = regularizeIRPF;
830 MappingSet
set =
new MappingSet();
832 new String[] {
"id",
"documentNumber",
"documentDate" },
833 new String[] {
"documentDefinition",
"notes",
"receiptDate",
"draft",
"documentLines",
834 "currency",
"contract",
"forcedView",
"relatedPath",
"ancestors",
"descendants",
"registers",
835 "conciliateRegister",
"regularizeVAT",
"regularizeIRPF",
"noAncestors",
"noDescendants" });
837 new String[] {
"id",
"name" },
840 new String[] {
"id",
"name" },
843 new String[] {
"id",
"name" },
847 new String[] {
"ancestor",
"descendant" });
849 new String[] {
"id" },
852 new String[] {
"quantity",
"price",
"tax",
"retention",
"discountPerCent",
"discountMoney" },
853 new String[] {
"concept",
"product",
"productByContractor",
"store",
854 "lineType",
"contractPreference"});
855 set.addMapping(
Product.class, 3,
856 new String[] {
"id",
"productCode" },
857 new String[] {
"description" });
859 new String[] {
"contractorCode" },
860 new String[] {
"contract" });
862 new String[] {
"id",
"name" },
865 new String[] {
"id",
"name" },
868 new String[] {
"name" },
871 new String[] {
"name" },
static long getMaxLongIdFromString(Dao dao, String table, String field)
static IElephantEntity getController(String path)
ContractDefinition getContractDefinition()
ContractPreference getDefaultContractPreference()
ContractDefinitionNotes getNotes()
ContractDefinition getContractDefinition()
Department getDepartment()
Headquarters getHeadquarters()
void setStore(Contract store)
void setEquivalenceSurcharge(double equivalenceSurcharge)
void setLineOrder(int lineOrder)
void setContractPreference(ContractPreference contractPreference)
void setQuantity(double quantity)
void setDiscountMoney(double discountMoney)
void setDiscountPerCent(double discountPerCent)
void setLineType(LineType lineType)
void setRetention(double retention)
void setDocument(Document document)
void setProduct(Product product)
void setPrice(double price)
void setProductByContractor(ProductByContractor productByContractor)
void setConcept(String concept)
void setDescendant(Document descendant)
void setAncestor(Document ancestor)
DocumentDefinition getDescendant()
DocumentDefinition getAncestor()
void setForcedView(RegisterView forcedView)
void setDocumentLines(Set< DocumentLine > documentLines)
Set< Register > getRegisters()
void setDocumentNumber(String documentNumber)
Collection< Contract > getStores()
void setDocumentDate(Date documentDate)
void assignTableOrder(Collection< DocumentLine > lines)
RegisterView getForcedView()
Contract getDefaultStore()
Collection< Collection > collections()
void setRegularizeIRPF(boolean regularizeIRPF)
Set< DocumentRelation > getDescendants()
String getDocDescription()
void copyFrom(Document doc, boolean shallowCopy)
Object doAction(Date now, String data)
boolean isRegularizeVAT()
void setContract(Contract contract)
void setRegularizeVAT(boolean regularizeVAT)
void setRegisters(Set< Register > registers)
String getCleanFullNotes()
void setNoDescendants(boolean noDescendants)
void appendLines(Document relDoc, String header, DocumentWorkflow workflow)
String getDocumentNumber()
void setRelatedPath(String relatedPath)
Collection< DocumentWorkflow > getWorkflows()
void setDraft(boolean draft)
IElephantEntity getRelated()
void setCurrency(Currency currency)
boolean isConciliateRegister()
boolean isRegularizeIRPF()
transient boolean regularizeIRPF
void setDescendants(Set< DocumentRelation > descendants)
Collection< Contact > getActualHqContacts()
void setNoAncestors(boolean noAncestors)
void setConciliateRegister(boolean conciliateRegister)
ContractPreference getDefaultContractPreference()
Set< DocumentLine > getDocumentLines()
void setDocumentDefinition(DocumentDefinition documentDefinition)
MappingSet getSerializerMappings()
String getDocumentString()
void setReceiptDate(Date receiptDate)
void setNotes(String notes)
boolean isNoDescendants()
Collection< DocumentWorkflow > getWorkflows(boolean forward, boolean missing)
LineType getDefaultLineType()
Set< DocumentRelation > getUpdatedDescendants()
void setQuote(double quote)
Collection< ContractFlow > getContractFlows()
DocumentAmountsByBook getAmountsByBook(BookDefinition bookDefinition)
void backFrom(Document doc, String header, DocumentWorkflow workflow)
DocumentAmounts getAmounts()
transient boolean conciliateRegister
transient boolean regularizeVAT
DocumentDefinition getDocumentDefinition()
void setAncestors(Set< DocumentRelation > ancestors)
Collection< LineType > getLineTypes()
void flowFrom(Document doc, String header, DocumentWorkflow workflow)
void appendAmounts(Document relDoc, String header, DocumentWorkflow workflow)
void setContractPreference(ContractPreference contractPreference)
Set< BookRegister > getBookRegisters()
static void clearInactives(Collection< Contract > contracts)
AmountTaxableSet getTaxables()
Collection< Contract > getRelatedStores(Contract contract)
boolean isNotLoaded(Object o, String attribute)
static String cleanLinks(String message)
default void prepareSave()