@@ -77,32 +77,41 @@ export default function Povijest() {
7777
7878 const getArticlesReport = ( ) => {
7979 const articleMap = { } ;
80-
80+
8181 filteredTransactions . forEach ( t => {
8282 if ( t . receipt ?. items && t . receipt . status !== 'STORNO' && t . receipt . status !== 'RACUN_STORNIRAN' ) {
83+ const isCash = t . receipt . paymentType === 'GOTOVINA' ;
8384 t . receipt . items . forEach ( item => {
8485 const name = item . article ?. name || "N/A" ;
8586 if ( ! articleMap [ name ] ) {
8687 articleMap [ name ] = {
8788 name,
8889 price : item . price ,
8990 quantity : 0 ,
91+ cashTotal : 0 ,
92+ cardTotal : 0 ,
9093 total : 0
9194 } ;
9295 }
9396 const qty = parseFloat ( item . quantity ) ;
97+ const itemTotal = qty * Math . abs ( parseFloat ( item . price ) ) ;
9498 articleMap [ name ] . quantity += qty ;
95- articleMap [ name ] . total += qty * Math . abs ( parseFloat ( item . price ) ) ;
99+ articleMap [ name ] . total += itemTotal ;
100+ if ( isCash ) {
101+ articleMap [ name ] . cashTotal += itemTotal ;
102+ } else {
103+ articleMap [ name ] . cardTotal += itemTotal ;
104+ }
96105 } ) ;
97106 }
98107 } ) ;
99-
108+
100109 return Object . values ( articleMap ) . sort ( ( a , b ) => b . total - a . total ) ;
101110 } ;
102111
103112 const getPaymentReport = ( ) => {
104113 const paymentMap = { } ;
105-
114+
106115 filteredTransactions . forEach ( t => {
107116 if ( t . receipt ?. paymentType && t . receipt . status !== 'STORNO' && t . receipt . status !== 'RACUN_STORNIRAN' ) {
108117 const method = t . receipt . paymentType ;
@@ -113,16 +122,33 @@ export default function Povijest() {
113122 paymentMap [ method ] . count += 1 ;
114123 }
115124 } ) ;
116-
125+
117126 return Object . values ( paymentMap ) . sort ( ( a , b ) => b . total - a . total ) ;
118127 } ;
119128
129+ const getProdajnaMjestaReport = ( ) => {
130+ const map = { } ;
131+ filteredTransactions . forEach ( t => {
132+ if ( t . receipt ?. status !== 'STORNO' && t . receipt ?. status !== 'RACUN_STORNIRAN' ) {
133+ const name = t . receipt ?. prodajnoMjestoNaziv || "Nepoznato" ;
134+ if ( ! map [ name ] ) map [ name ] = { name, total : 0 , count : 0 , gotovina : 0 , kartica : 0 } ;
135+ const amt = parseFloat ( t . amount ) ;
136+ map [ name ] . total += amt ;
137+ map [ name ] . count += 1 ;
138+ const pt = t . receipt ?. paymentType ;
139+ if ( pt === 'GOTOVINA' ) map [ name ] . gotovina += amt ;
140+ else if ( pt === 'KARTICA' ) map [ name ] . kartica += amt ;
141+ }
142+ } ) ;
143+ return Object . values ( map ) . sort ( ( a , b ) => b . total - a . total ) ;
144+ } ;
145+
120146 const exportTransactionsToExcel = ( ) => {
121147 const excelData = filteredTransactions . map ( t => ( {
122148 "Broj Računa" : t . receipt ?. invoiceNumber || "N/A" ,
123149 "Iznos (€)" : parseFloat ( t . amount ) . toFixed ( 2 ) ,
124150 "Plaćanje" : t . receipt ?. paymentType || "N/A" ,
125- "Status" : t . receipt ?. status === 'STORNO' ? 'Storno' : t . receipt ?. status === 'RACUN_STORNIRAN' ? 'Otkazano' : 'Gotovo ' ,
151+ "Status" : t . receipt ?. status === 'STORNO' ? 'Storno' : t . receipt ?. status === 'RACUN_STORNIRAN' ? 'Otkazano' : 'Aktivan ' ,
126152 "Prodavač" : t . user ?. name || "Nepoznato" ,
127153 "Datum" : new Date ( t . createdAt ) . toLocaleDateString ( "hr-HR" ) ,
128154 "Vrijeme" : new Date ( t . createdAt ) . toLocaleTimeString ( "hr-HR" , { hour : '2-digit' , minute : '2-digit' , second : '2-digit' } ) ,
@@ -141,6 +167,8 @@ export default function Povijest() {
141167 "Naziv Artikla" : a . name ,
142168 "Cijena (€)" : parseFloat ( a . price ) . toFixed ( 2 ) ,
143169 "Količina" : a . quantity ,
170+ "Gotovina (€)" : a . cashTotal . toFixed ( 2 ) ,
171+ "Kartica (€)" : a . cardTotal . toFixed ( 2 ) ,
144172 "Suma (€)" : a . total . toFixed ( 2 )
145173 } ) ) ;
146174
@@ -154,7 +182,7 @@ export default function Povijest() {
154182 const paymentReport = getPaymentReport ( ) ;
155183 const excelData = paymentReport . map ( p => ( {
156184 "Način Plaćanja" : p . method ,
157- "Broj Računa " : p . count ,
185+ "Količina " : p . count ,
158186 "Suma (€)" : p . total . toFixed ( 2 )
159187 } ) ) ;
160188
@@ -164,6 +192,21 @@ export default function Povijest() {
164192 XLSX . writeFile ( workbook , `KSET_Izvjestaj_Placanje_${ startDate } _${ endDate } .xlsx` ) ;
165193 } ;
166194
195+ const exportProdajnaMjestaToExcel = ( ) => {
196+ const report = getProdajnaMjestaReport ( ) ;
197+ const excelData = report . map ( p => ( {
198+ "Prodajno Mjesto" : p . name ,
199+ "Količina" : p . count ,
200+ "Gotovina (€)" : p . gotovina . toFixed ( 2 ) ,
201+ "Kartica (€)" : p . kartica . toFixed ( 2 ) ,
202+ "Suma (€)" : p . total . toFixed ( 2 )
203+ } ) ) ;
204+ const worksheet = XLSX . utils . json_to_sheet ( excelData ) ;
205+ const workbook = XLSX . utils . book_new ( ) ;
206+ XLSX . utils . book_append_sheet ( workbook , worksheet , "Prodaja po Prodajnim Mjestima" ) ;
207+ XLSX . writeFile ( workbook , `KSET_Izvjestaj_ProdajnaMjesta_${ startDate } _${ endDate } .xlsx` ) ;
208+ } ;
209+
167210 const handleExport = ( ) => {
168211 switch ( reportType ) {
169212 case 'transactions' :
@@ -175,6 +218,9 @@ export default function Povijest() {
175218 case 'payment' :
176219 exportPaymentToExcel ( ) ;
177220 break ;
221+ case 'prodajnaMjesta' :
222+ exportProdajnaMjestaToExcel ( ) ;
223+ break ;
178224 default :
179225 break ;
180226 }
@@ -190,7 +236,9 @@ export default function Povijest() {
190236
191237 const articlesReport = getArticlesReport ( ) ;
192238 const paymentReport = getPaymentReport ( ) ;
193- const totalAmount = filteredTransactions . reduce ( ( sum , t ) => sum + parseFloat ( t . amount ) , 0 ) ;
239+ const totalAmount = filteredTransactions
240+ . filter ( t => t . receipt ?. status !== 'STORNO' && t . receipt ?. status !== 'RACUN_STORNIRAN' )
241+ . reduce ( ( sum , t ) => sum + parseFloat ( t . amount ) , 0 ) ;
194242
195243 if ( loading ) return < div style = { { padding : '40px' } } > Učitavanje...</ div > ;
196244
@@ -223,6 +271,7 @@ export default function Povijest() {
223271 < option value = "transactions" > Povijest transakcija</ option >
224272 < option value = "articles" > Prodaja po artiklima</ option >
225273 < option value = "payment" > Prodaja po načinu plaćanja</ option >
274+ < option value = "prodajnaMjesta" > Prodaja po prodajnim mjestima</ option >
226275 </ select >
227276 </ div >
228277
@@ -490,6 +539,8 @@ export default function Povijest() {
490539 < th style = { thStyle } > Naziv Artikla</ th >
491540 < th style = { thStyle } > Cijena</ th >
492541 < th style = { thStyle } > Količina</ th >
542+ < th style = { thStyle } > Gotovina</ th >
543+ < th style = { thStyle } > Kartica</ th >
493544 < th style = { thStyle } > Suma</ th >
494545 </ tr >
495546 </ thead >
@@ -499,11 +550,13 @@ export default function Povijest() {
499550 < td style = { tdStyle } > { article . name } </ td >
500551 < td style = { tdStyle } > { parseFloat ( article . price ) . toFixed ( 2 ) } €</ td >
501552 < td style = { tdStyle } > { article . quantity } </ td >
553+ < td style = { tdStyle } > { article . cashTotal . toFixed ( 2 ) } €</ td >
554+ < td style = { tdStyle } > { article . cardTotal . toFixed ( 2 ) } €</ td >
502555 < td style = { { ...tdStyle , fontWeight : '600' } } > { article . total . toFixed ( 2 ) } €</ td >
503556 </ tr >
504557 ) ) }
505558 < tr style = { { backgroundColor : '#edf2f7' , fontWeight : 'bold' } } >
506- < td colSpan = "3 " style = { { ...tdStyle , textAlign : 'right' } } > UKUPNO:</ td >
559+ < td colSpan = "5 " style = { { ...tdStyle , textAlign : 'right' } } > UKUPNO:</ td >
507560 < td style = { { ...tdStyle , fontWeight : 'bold' } } > { articlesReport . reduce ( ( sum , a ) => sum + a . total , 0 ) . toFixed ( 2 ) } €</ td >
508561 </ tr >
509562 </ tbody >
@@ -515,7 +568,7 @@ export default function Povijest() {
515568 < thead >
516569 < tr style = { { backgroundColor : '#edf2f7' , textAlign : 'left' } } >
517570 < th style = { thStyle } > Način Plaćanja</ th >
518- < th style = { thStyle } > Broj Računa </ th >
571+ < th style = { thStyle } > Količina </ th >
519572 < th style = { thStyle } > Suma</ th >
520573 </ tr >
521574 </ thead >
@@ -535,6 +588,41 @@ export default function Povijest() {
535588 </ tbody >
536589 </ table >
537590 ) }
591+
592+ { reportType === 'prodajnaMjesta' && ( ( ) => {
593+ const report = getProdajnaMjestaReport ( ) ;
594+ return (
595+ < table style = { { width : '100%' , borderCollapse : 'collapse' } } >
596+ < thead >
597+ < tr style = { { backgroundColor : '#edf2f7' , textAlign : 'left' } } >
598+ < th style = { thStyle } > Prodajno Mjesto</ th >
599+ < th style = { thStyle } > Količina</ th >
600+ < th style = { thStyle } > Gotovina</ th >
601+ < th style = { thStyle } > Kartica</ th >
602+ < th style = { thStyle } > Suma</ th >
603+ </ tr >
604+ </ thead >
605+ < tbody >
606+ { report . map ( ( pm , idx ) => (
607+ < tr key = { idx } style = { { borderBottom : '1px solid #edf2f7' } } >
608+ < td style = { tdStyle } > { pm . name } </ td >
609+ < td style = { tdStyle } > { pm . count } </ td >
610+ < td style = { tdStyle } > { pm . gotovina . toFixed ( 2 ) } €</ td >
611+ < td style = { tdStyle } > { pm . kartica . toFixed ( 2 ) } €</ td >
612+ < td style = { { ...tdStyle , fontWeight : '600' } } > { pm . total . toFixed ( 2 ) } €</ td >
613+ </ tr >
614+ ) ) }
615+ < tr style = { { backgroundColor : '#edf2f7' , fontWeight : 'bold' } } >
616+ < td colSpan = "1" style = { { ...tdStyle , textAlign : 'right' } } > UKUPNO:</ td >
617+ < td style = { tdStyle } > { report . reduce ( ( sum , p ) => sum + p . count , 0 ) } </ td >
618+ < td style = { tdStyle } > { report . reduce ( ( sum , p ) => sum + p . gotovina , 0 ) . toFixed ( 2 ) } €</ td >
619+ < td style = { tdStyle } > { report . reduce ( ( sum , p ) => sum + p . kartica , 0 ) . toFixed ( 2 ) } €</ td >
620+ < td style = { { ...tdStyle , fontWeight : 'bold' } } > { report . reduce ( ( sum , p ) => sum + p . total , 0 ) . toFixed ( 2 ) } €</ td >
621+ </ tr >
622+ </ tbody >
623+ </ table >
624+ ) ;
625+ } ) ( ) }
538626 </ div >
539627 </ div >
540628 ) ;
@@ -546,7 +634,7 @@ function StatusBadge({ status }) {
546634 } ;
547635 if ( status === 'STORNO' ) return < span style = { { ...styles , backgroundColor : '#fed7d7' , color : '#9b2c2c' } } > Storno</ span > ;
548636 if ( status === 'RACUN_STORNIRAN' ) return < span style = { { ...styles , backgroundColor : '#feebc8' , color : '#9c4221' } } > Otkazano</ span > ;
549- return < span style = { { ...styles , backgroundColor : '#c6f6d5' , color : '#22543d' } } > Gotovo </ span > ;
637+ return < span style = { { ...styles , backgroundColor : '#c6f6d5' , color : '#22543d' } } > Aktivan </ span > ;
550638}
551639
552640const thStyle = { padding : '15px' , fontSize : '14px' , color : '#4a5568' , textTransform : 'uppercase' , letterSpacing : '0.05em' } ;
0 commit comments