From 838dc6b8b5ac10fe9ff236f5288706f54c6a0465 Mon Sep 17 00:00:00 2001
From: Jakob Wennberg
{formatAmount(ledger.total_outstanding)} kr
+{ledger.unpaid_count} fakturor
+{formatAmount(ledger.total_current)} kr
+{formatAmount(ledger.total_overdue)} kr
+| Leverantör | +Ej förfallet | +1-30 dagar | +31-60 dagar | +61-90 dagar | +90+ dagar | +Totalt | +
|---|---|---|---|---|---|---|
| {entry.supplier_name} | +{entry.current > 0 ? formatAmount(entry.current) : ''} | +{entry.days_1_30 > 0 ? formatAmount(entry.days_1_30) : ''} | +{entry.days_31_60 > 0 ? formatAmount(entry.days_31_60) : ''} | +{entry.days_61_90 > 0 ? formatAmount(entry.days_61_90) : ''} | +{entry.days_90_plus > 0 ? formatAmount(entry.days_90_plus) : ''} | +{formatAmount(entry.total_outstanding)} | +
| Summa | +{formatAmount(ledger.entries.reduce((s, e) => s + e.current, 0))} | +{formatAmount(ledger.entries.reduce((s, e) => s + e.days_1_30, 0))} | +{formatAmount(ledger.entries.reduce((s, e) => s + e.days_31_60, 0))} | +{formatAmount(ledger.entries.reduce((s, e) => s + e.days_61_90, 0))} | +{formatAmount(ledger.entries.reduce((s, e) => s + e.days_90_plus, 0))} | +{formatAmount(ledger.total_outstanding)} | +
+ {settings?.entity_type === 'aktiebolag' + ? 'Aktiebolag måste använda faktureringsmetoden enligt BFL.' + : 'Kontantmetoden är tillgänglig för enskild firma med omsättning under 3 MSEK.'} +
+Fakturan hittades inte
+ ++ {invoice.supplier?.name} | Faktura {invoice.supplier_invoice_number} +
+| Beskrivning | +Antal | +Enhet | +À-pris | +Konto | +Moms% | +Belopp | +Moms | +
|---|---|---|---|---|---|---|---|
| {item.description} | +{item.quantity} | +{item.unit} | +{formatAmount(item.unit_price)} | +{item.account_number} | +{Math.round(item.vat_rate * 100)}% | +{formatAmount(item.line_total)} | +{formatAmount(item.vat_amount)} | +
| Datum | +Belopp | +Verifikation | +Anteckning | +
|---|---|---|---|
| {p.payment_date} | +{formatAmount(p.amount)} {p.currency} | ++ {p.journal_entry_id ? ( + + {p.journal_entry_id.substring(0, 8)}... + + ) : '-'} + | +{p.notes || '-'} | +
Ingen registreringsverifikation (kontantmetoden)
+ )} + {invoice.payment_journal_entry_id && ( +{invoice.notes}
++ Registrera en inkommande faktura (uppfyller BFL verifikationskrav) +
++ Registrera och hantera inkommande fakturor +
+{formatAmount(totalUnpaid)} kr
++ {invoices.filter((i) => !['paid', 'credited'].includes(i.status)).length} fakturor +
+{formatAmount(overdueAmount)} kr
+{overdueCount} fakturor
+{invoices.length}
++ {activeTab === 'all' + ? 'Registrera din första leverantörsfaktura' + : 'Inga fakturor i denna kategori'} +
+ {activeTab === 'all' && ( + + + + )} +| Ankomst | +Leverantör | +Fakturanr | +Fakturadatum | +Förfaller | +Belopp | +Kvar att betala | +Status | +
|---|---|---|---|---|---|---|---|
| {inv.arrival_number} | ++ + {inv.supplier?.name || '-'} + + | ++ + {inv.supplier_invoice_number} + + | +{inv.invoice_date} | +{inv.due_date} | +{formatAmount(inv.total)} | +{formatAmount(inv.remaining_amount)} | +
+ |
+
Leverantören hittades inte
+ ++ {supplierTypeLabels[supplier.supplier_type]} + {supplier.org_number && ` | Org.nr: ${supplier.org_number}`} +
+{formatAmount(supplier.stats?.total_outstanding || 0)} kr
+{formatAmount(supplier.stats?.total_paid || 0)} kr
+{supplier.stats?.invoice_count || 0}
+E-post: {supplier.email}
} + {supplier.phone &&Telefon: {supplier.phone}
} + {supplier.address_line1 &&{supplier.address_line1}
} + {supplier.postal_code &&{supplier.postal_code} {supplier.city}
} + {supplier.vat_number &&VAT: {supplier.vat_number}
} +Bankgiro: {supplier.bankgiro}
} + {supplier.plusgiro &&Plusgiro: {supplier.plusgiro}
} + {supplier.iban &&IBAN: {supplier.iban}
} + {supplier.bic &&BIC: {supplier.bic}
} +Betalningsvillkor: {supplier.default_payment_terms} dagar
+Valuta: {supplier.default_currency}
+ {supplier.default_expense_account &&Kostnadskonto: {supplier.default_expense_account}
} ++ Inga fakturor registrerade för denna leverantör +
+ ) : ( +| Ankomst | +Fakturanr | +Datum | +Förfaller | +Belopp | +Kvar | +Status | +
|---|---|---|---|---|---|---|
| {inv.arrival_number} | ++ + {inv.supplier_invoice_number} + + | +{inv.invoice_date} | +{inv.due_date} | +{formatAmount(inv.total)} kr | +{formatAmount(inv.remaining_amount)} kr | +
+ |
+
+ Hantera dina leverantörer och deras betalningsuppgifter +
++ Inga leverantörer matchar "{searchTerm}" +
++ Lägg till din första leverantör för att börja registrera inköpsfakturor +
+ +Org.nr: {supplier.org_number}
+ )} + {supplier.bankgiro && ( +Bankgiro: {supplier.bankgiro}
+ )} + {supplier.city && ( +{supplier.city}, {supplier.country}
+ )} +- Steg {currentStep + 1} av {tourSteps.length} -
-- {step.description} -
- - {/* Progress dots */} -- Dessa uppgifter visas på dina fakturor så att kunder kan betala dig. -
-- För kunder utanför Sverige som betalar via banköverföring. -
- -Vad är IBAN?
-Internationellt bankkontonummer. Svenska IBAN börjar med SE och har 24 tecken totalt.
-Din bank kan ge dig ditt IBAN - kolla internetbanken eller kontakta dem.
-Vad är BIC/SWIFT?
-Bankens internationella id-kod. Används tillsammans med IBAN för utlandsbetalningar.
-{message}
- )} -- Disponibelt att spendera -
- -- {formatSEK(breakdown.disponibelt)} -
- -- Total: {formatSEK(totalBalance)} -
- -- ⓘ Detta är en uppskattning. Faktisk skatt kan variera. -
-- {transaction.counterparty_name || transaction.description} -
- -- {formatSEK(transaction.amount)} -
- -- {new Date(transaction.booking_date).toLocaleDateString('sv-SE')} -
-1b8+Z_nr!5`W>m;5)m*fj zy;{iJP2bB-YPf{yWJ&CdNmPom?(46(`{Dih{PKRiKJWMY^?AMXg97OoBTFL~42JP# z(Dp;Sd>JSNH1U5Bh|n@jVjNC^!B(0sV+E|T3J-%BH2cyh2hLPYSM3d4OE=36D>!{B z^hDnhv+KJ+;X1!2I1=azho`mWrkLn9TAQ8NP j!xl^_fs>;{(XxV(Iv;Xc zkp7m8IhU46sce%51>ypRQKzb0)E&n23m2 zu^XUtR%hZgK&p7mV)we-uh~EqxL*@ULr!TpZH l89{G=PrdJ?l8Ja$-RHbWS}(XiE`K{jFl7zDE0tRW zq>|ymvnCyR+7>piy1KTsw6uFrrE<3MWO-PY9Btr*eL&h;$O>uVY)H=msp&HiUs88J zpoq~8o%?B`bCl!aS&js;#>UT8s$;Rjh6Z!nup$QCx`-c8xCPJZ-29UL3|z&6BrRKb zgTCtbv^{T(!^deaR+ChAK1j%|ZE_LA^N`bKlUVZZD5}_sd2c&AAFHN_$H&LFdU?Ha zOi4+R)6MOBeUVd 8;ly0)PGegaHx1>cnKiF64jmKvybw*Hmza zD2zgTbdC1GhuypOB_x#@WQ+s$H_o_`B}=5i_q|pta)enGiE3}1pQiW%b>N|bDg3)> zsUBhz6M~c<%|niHk6lxt9gbkII&Q)`eB`}z1jkj0Lp#6F#Zu9X`rwn^>v}nND6&OM zG~!eJY;??C|C4C5n@|mTyB!~Pm0T0JBP-`Ef4fsZdCQj-B9Tb=jPxm>^hTW!tf<&g z?w}mZ`c`tghTX-gtw%g+N^GlhzE@d$wkS%j?;qU$mqOOc36JDyYi uofX$2zAauW%$DMoT1m0qfN}u?awBhBIbrhLqcWSt%g5;Q;+Dg3i?LU zWHsM<*2gP1W#)TK#(Vwq>TCH6E2f1NJ$=jfJ*Ej|(=pxBxXPY}(I@;D!(or+vgM6X Oufu$O0%;;D!1@>Zho05| literal 0 HcmV?d00001 diff --git a/public/icons/icon-192.png b/public/icons/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..17df5681917871b4d73bb0ce312c31c74c23cd4c GIT binary patch literal 2066 zcmcJQZB!Fy7Jz3G7!n|m2!V7|2%#b%khq3Im0bb^1fe+*vdD*?1o;XdA{K;n`I- =@vM2`_3vlC8Wqb9J@R5-Awh8N=5xaFHK~9_- z+hCJWN_gnF?@;Aahg!?eEH0eb(=)Z>{4r_&(u>Ol1H_#2pXcYrInNKi9(Y<<^D;&t zC~`M$(R=5+vtC487t TLZb4QN^o;-mXVZn}nL _|0=@}y>FDsDlfCE zctnNPwux^EiJEWK8m(4an3?}|G&Ih 28tAN0?Df+{}I zhvV;iJi!!q-z~x39JvT*okf-|!Kb et5@xqfK(5_H9k0ltla?3PC>RCflL9GL3X}4 z`|W{!Kh+(O2E6*$cmX>2ShUOQjn!Cuj{agOS3 T{Kri4ECAb)%?j;x5>m5Bmwfx*+cWFV?1_MLuCH#;YqcA;v!=7tJ z`(_M-+lQ=2_{8OFJg#4^{Qr>3|0K>!M|x!odndo&Kb^2QFRwFjw}{%qOXaEpo5#n; zjrlu6r2qYbn|Ld~l9-9%cvC5mqnz{>gP|C@sr>NM9}HH!f8}~LJKM+4&*^@xHJ&0C z&KZG1m9#DbXr*Lx3A=z|>?J$ll`W8iLQ55b$}R?tr$592td{`pBmpLxol*jUoMpB= zAO&)n*}j?q XbwY2LnMqrs6K!7;ru(4KTX!b(4R_-2ns0_)9ahiPGLP{T$)^^4DI95a zhTO^z^GM6g>OxFqzN-yMEv>4{NPl+=l0`z({v2HHz8r8$UvT3-roE_+;QJKyyn@ck z&r+7%@frH?_Np##X}Cu}Eh2w8bMGq~CHY*m!fL %8l%E$tLnIo A@Gzgh`p;dDjYs#r3{@=F_FkHGezY@ag|m}i zN~aCVnt2SbExJB( _UuQt0I1@EqqD?SfTefi~wOY?Rvg|Y4Q eskO+p_t3-rXSr8bD`)Xb9*PPV@H;~#mH!5+LMkT! literal 0 HcmV?d00001 diff --git a/public/icons/icon-384.png b/public/icons/icon-384.png new file mode 100644 index 0000000000000000000000000000000000000000..709c5248ff60f5eeb529ba6ef29031dd6c1f0333 GIT binary patch literal 5586 zcmeHLc~n#9wm%t643Zed0W=020BtJ-K_rABfIOu#RXKo2F+3co3_%cy2$+D1N(F@V zgbI 4yXJ$wwo zPxpp+G-z|H#KmK<`Nl2pcKhbSTW2rcEr_-i&Xm76yE=hYw<9xdQ(a7E<=bn=cbm&( zj@mZDo_vLJDmAD!wW=h#O8B6)qocZ7T%F$2<`R%2Ga@lLe8FS8*PMdrPO-Q#ZEHkd z=o-JGmJ+X~`>=9Ls1^mM{r-qZ96%3w5nDAk;k!C{L6MV--KCzBl1vlCtu0kFo3el+ z`)%6yx86@|-U=&U!^%w32H%GmoVIH#8=fr{zs-qX?`vcYQY`(fI_qtM`ydoZt!T z(|hlw(rsg{>U?bKey3kb#}N*Nbvb4fg@uL9HZYQ5_|$IL)YagqBSn|PSwavG9EO#3 zfj=p(v>%=@bzK`cFApS`eC^|%s&7B{Ht_S1kPrpVg`USwJWXTBWZ#j!nu7N2+c%_d zbnN@_vSybhkunHZrF&zWNpW7N-%N`_xg(?UskI(rN#ul675ho%Zn%u>mw4xi#Xd&q z__aiBhJ3WP@2!perTttIeI!&mi6|Rz W;tlT){SGo;BBYXW#w@k0lA_D#TYmHpU> L>MT z^ -JBLC`7GAAo4J~z8b6hfB7W>r(#ZM7 zl-07VefsHYJz@q3CnrT;WwU<7-3|%x%N~)q`qYS0wMepfr#c}?zt$*rq|(ZcTgATb zOGcx)mJd8UKQgImyk|#M$3iK`Jl`6ilJ0*gj6-58|J4DGKN<>k2FDwyou?hc@q$C4 zw9hLu(=Y_xom}Qb!vsZ^sbi%vaSUr^Zpl9^!)d ut#<= 6BTvf_^8O4p%LNFA|k;tAuca5TV{lKAP9!28}Ufw zuIPcki>;Q(ezAqrcXGOo7;1NJjx3{UPP!X4Cpzlm&5?Dw8X0=WwISNXvIlre2P7@q zH9q|(R^!}K)Espj(u7CSM#I~KI>NRgXrZE$8gDBX5>Qc&Y~J1U!l (-l z%C ?{<#bF5A1EV! %0O3+7raB9S@R z9QnRrXcapoX&tEkRWe!@iH&KbzmnmhOcLkNE}R_t4#Q@&^uAh}PLQ{X5N?w>sr7gf zzZMVG_^-|;v2np+o)7SlfWW9di1m~OVfmaw@*}(mbH{QcQgpcN?k$*&U1o?K!Xd02 z@>{(OT!=7_j(!6z8wT9U4#AmYf*}d{0=SSvy``>@77z4>M|TC^Ko j zo#TpEGKZ5G2AgkVa;>93zjPo6X+^FD!1kMQ_Co;@93S)8V76CgC_*3%#0E==jucRE z77)QA>3t4PM~1ijwuFJX(}`P4L?DB3R~)7u3rO=&W<#w*f^;0{1R6VdhQO_Fv#Z)Z z0e~dqA4*S%;$T59e80koKX%ffhYh*|j>9(JDP=M+pvYqv>9D75sgWWCB!)=uS|=?V zY0_0^NTON#LXbxQlCE6)376su={!B%@e^L2u=q3$#1af?2NU|Y5sl^<@PFJ-CI4N_ z{1p^ZP^{y}+f&ZBg;%)!cDy=#%$jHf-B|Gqx_s|y?7$|ntgIX~l XGo^$eT* gF->7 z{<9N8R*X9?q9Yt|?9g6N)tYYcQR_1_$aaOy_pRa+kX)5nnr89;zdZ=Gng*CvX36-N zS^vZq+Rp2~n3HMjaiRWEjoY^NKjIcUuegMhF0}mfS6= U-C(ab{!1R4n?+nutI|EcvjG0mXOz!eNAM?%(ydn3m zBZ9?Aw=@(&=2F8G5~TyOECHi!CzBUlIX+!axXD@&w+jt%g%FI9S^GE5RcuR?%BN)N z!TZ?|?fLW%1V#WsEY8}{NqUG3)t5jpStTVUMW^=Qo(i$_@OVBt*!tjj5xo4Z9eS5} z#`?%2z`2)m*ROr%GMS@$Ha{abEIu98jHV=5Y2W|0Bn0X{C~DlP9wr|?i5%{Kv9wt| zt`~eXu8;V(nf^EC>pimgE&)2&PZaO^WNxJ!=DKl&Ty50<3rclNooZV3bL*^--|`{} z89*QUM=_d*Gw;7D5Kmnv&0tVfZ_3<@+ZR;fINpAER@-g@Nx-Ac#71N07XLbAe>Cy) z&ED0UkX4W6kO6U}cp%fqYsT~ne$M@!kdLIicRb0|r`$c)YNSvcdq=5ni0JA*RQb&4 zvl3<|Dw3=Gk+qG-yWAcYMh}=rwk6(8w*u{(kKCQ&WUMqE-l5(#y!({NyCn{%jYUaX z6lq>fpAOf|$G8;WJPIq5?>iKXeD4^rG(_5ucyGY198_Mv?@-uuMET=L%RvaAjtt_( zs>%HWK6c};B0V!y_a?PKrWol-4K
%x5afnYqWBYTeGSt@S@a%q@D|rrPJ}MfK%adqC>vJ z M(!!@Gl3vn-*2*J07XJ1=7$rZT`q~u=$#K#nvO0mA1_Vw~h;SL-s0S dr@R#^$m^NeR_pk^)?i5sxj4ITFLdN2{tpc=7+L@T literal 0 HcmV?d00001 diff --git a/public/icons/icon-512.png b/public/icons/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..83bff4a69094e71736c9c3b88f124408a454c45a GIT binary patch literal 8625 zcmeHNc~DbXy1z* 1cHcwfJvGbv;m>9 z9;hIos4bUWWQTYWn`M+u4Fp*dmR1l#BFY-befQ>uV843xs@~N5>ortSP<2ke^L^j> zw)6Yt+L1%{q^0Dg00592_U}0g0C?nIJfKEI{(KI8GlTq5XYM~4000^*&|e&IJ4Fuw zD1gJBoyUVyMBS%j+-jwM?+LL%-> @hrIO_~)vR z 7Du6w=zT=LcWk(;h1 zZf8nfjEufa`2^F_)`g71(ooyx$=QjN_bEf=zv@d9lad6<12y!(0D8AGJ!swZFH}J$ zSVJEVOGvtL?v@t>5H!tvgunIPHvLXN()&3x=MiXPRB^G(Cb`kp?7L%;-Y@vNmi-%D z0|NsS2P|)Nous=so_E8iA2esMaYUUL(9hr{s|Lfuj*)(EZ*TvdJ^ck-?&ULrNhjk9 zAu9;~4YrYNc7%R--Slg)+{@LqA5W^@6w}z)_$lhtjDu~`z=Hza?&Aca9)r!PEL#~| z0NQT1*fE{2rU8%wMw{w5gK>3ZmnE!DL% zf`>)TQQHT)SI2gon}~KueZse}K~6-BwC1^T{7ha>62K27bG?T8J(2QH)n9BTR^A>6 zs<1YqnTM_E_@VQ&e7okr!DZ?_ZGqj^-Id`LPr=d0LW>;=Ny+5dab{$0a#X>SC!cev zF2%~Fj%)2pj7taaMfY?&hHNk~$ `M3Gq*mo|ZkDzN zpI6 z#kE~1Om&{k`Vh2XW-!_p#Gwa6t>8?(v+PWo)1SI)72eNiPX}e|8{XzR&qg&bU&hMx z7-3~+5*03+S}Pn@U1nhA*G^_rSr3I4hM320eNXc3&WVQq!{PcNp|J-h9=VdcM0+V0 z7G6hBzEjg4#U@ *pVoy1CysdD!hCA%R@i6zRxCHzoR>kQ87} k4Pu^+!Tv%0mYsA$sXJquP{CvkO@=RI-< z+y4=9IAyGl7DlsbC~VnThh4r-Cb2nn%uj_{=8LDjn%CiRq4}Ux_TiX0z*=H>L7{Cg zVr`oB(66lU@VRGHlh`?eQg%fvP?=v=79vw8K}>JEYM*VGHy+oUmyWrWz~U50YwNr@ zBZo-fhvF4vHh77+Z4h()2@k^Is-eE8<>lLwp|~x|t-hoQvB0HHAcHp!rYmAZ!zF?% zroEenRdk*yGJ50;BJy<|4Tk^92DYFj$24BYOVSdT2fwFIi`8c-%8SSq;DQT=%foAM z5J|{Zh-`e5E|vxg;52C0O?inmjj!?na#yCpuu-s3Uc*e|6TO)IEkKto$N2mC2 ~V9U=-GB{u=HpZK)rN`EGiAi{2f s~(ckLW7uAm0i8QW+l5_nK$WwA>;+Fm|DKDBZotT9u^MC zz5B|UWCpA_p`tkE9*%9NjY-lD0w~%lm`2an0BS1o!~_WbL;$~2eimeBfd5gs-4AC+ zQNwQRYCEt>@lj7MkxKw}eoDs5B&p4gV9MERid`aw{DoN61+g~x1ufja&|;OHQj3o| zfXWYYnQTrlNn4>&{5x;qc0k+gsXAsHW6`+9oBQv=QgdqAeEd*Eyv3MYOt?RIHTl*o z9d{F2t>|#tr1|V%b4m#Sha#VW7!;!~YW!9}TMdu3@;+_Kg8MWU>UbqljYHv|B(yt+ zirV_)XueGjBnwMR5ze~w0ooQg6f19nWf!w1aWk#|)d7 4b z{!j<%Wa3I;nY3in)7kT%e7y2m@a0fJkKky;xxk+QJR!OjFxYmX{@b_Bn#l92o9qEF zmg|uL;s8MK%p;Q7>KlHr7MLT~G;5BucMj%4`LgD7L)6#X0nK`3lD=w>x;hTfizjIA zA*G<#XGMV61`G ;aaO9u!{VAFQFz9A<#<9rhMX}802pLSHAHm!dZn)N!qF=d%TUDB0@*Y z?AO+-5YLa1O9_kszJbOoKyTgkHTKsf8~gRHqS=|>5(LDoh$7mJHdM_%N4G`rDP;B) zLnNI~)ymWP#OJL*?X^E}VwwT}Uae!a>a**NLeC8+p7PxsmsRa(+3hColxhwPm=6ls z5u9H=fMtf;+%}5biF*9EzR0Ycuck=?2 O(PbR5 z4;`N%Lq&R{GbYDgp5FI}O=x DUkehW~)qbv!| 9 zAQO4-R=oVt)~$H?e^gr-?c{x10Te_jU;CQRPkk{Jn%gNpYIi%2BL?hRX4lH+$o&z> zjCYW+{2&HD$@_o;Q0V#se~A0y<-c-43xBow*FI!dxnyBBbtcSX5%;Ib=<}}8Pd=V< z%uZmnY|%Ir5w%;qxy7)=X0QJ_=iF4AfJ)+5`>{H3{{gwOjn2zjF|`0S?#QZMj{uje zFSIC7(6a~%+^j`{STS?E70Jz@gmwV4QYKNj{U_i4FZKz@qrhzcf5Aa%nk1 qZ_UXSm$gB_V08 z#8s(Z#i@v10=uS& 3LMfaR`1I9rY1Veu^g zSJ7}mJC0^Hp{3x_5MpK@K{8A$zzvp K+|POWgwpR zMtP1aEQR|=MYSJ3eAt(eA>_>4fbb_#PiH%Q+>i4FjzZOB3>t^*nr2uq>$OkN%d>?q zlpcB+j(F(t=!Ja=b+xiqB@$g&HpQBIvPo8FL SLpzNlMIbHlA%yy+~kYs|UM{ z82imb>ee^NVHpTM@BS8;k^&Z~v2tbNr?aY=sp1$!jybMJ?IyJAwgRX3X-fyWEq6qE zT#X}im| *WHY~m~IFM+9rCw|2z{9FAx9-$un7Thn$s_C4K~oIjV{XyLFzF8rJD2 zOB=PC@Ta7y8L|8o^ag*M1Id{tij$oSqL%GmFyU8n*uBo2f`S77o%C>TJiK2C 4KiYUUSf&i3@q LqELJ< zdefyKOD$J4etXANqD=sdIH>P g; z?MqmH!^ZvN5;;i)5IROn=JG^3XEa&&DGd=iJ?|8Z>@Syk;CjhFPM0wHyTF+YYTl_Z zoTB3OTzUaForZ64U9Tf-(aiye1^@N3<^;Lmi}HQ7OiN)R)qVpPkk2e0Z=m%xcRu#k z^~DbX0L}^hE 8Jb7V@{63z5!Ri~ljV;8Jn$10#-{<_qddh4Hv)aU z2w{(>`R&~ev0O2W=cH1n>Lriu_&Zz)?XhXzgy s-q+UXMY4fhq)=cqfvlHWlADuLKmLs(CVjHXPyb QRyaoCA0;Ft`Tt%sF@VBb;nDdm$pP28Ps-_6$U%vXvad!6u}aTrPLI**TNY z?;Py;VY84!52Hq1^XqkIU=TIxn`re>9(oWp>bXzQ(!d~U)XT`g5Ng>31Oief2wX8` z2O)eRv!p>l$^?NcrlEU>2SpH&GC|;qY3TmpmsJpuGC|;qDLV+^%h*&&4+aBWEEapY z)oL9-pwVcg`>NCF5Kx>5C_$+OR4$h_pU)@SIhRgA#bWW`a}W>+NSPpT#XdD04z=I! z$GY3?rniH3(R4Z`pg0jwf>I5rTCHlSREl+>P)IMJA`glnATUATiiPT+cDt?3W;4-; zE^0F+y{l6Dd(f^Tpai7?P_Nh1@p!zK8;!>C1HwNt0fB&&2?AG4*+B?j$Si3PkTOBw zifQQH;Xx4uq<@(p{w*B80(#@c0*Fn}qfgLn=puwsi^#PHR1ZA}jM_POxxNABKJ+lK z=h@f&L77bE1i-U_q15CBORE%B{0pIng8?{OS9GoAFE|sCX^P=YwvzM9ZFn_*xe$QI lBR?nkXY -^Z~X|R3On6km3LU002ovPDHLkV1hLM0r~&{ literal 0 HcmV?d00001 diff --git a/public/icons/icon-96.png b/public/icons/icon-96.png new file mode 100644 index 0000000000000000000000000000000000000000..ac06a872b583d4236ff89af1a85a7a0cc8763c4f GIT binary patch literal 843 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|V1v zPZ!6KiaBrRp7oLm6lwXb+B7e}>e!na7RQ(!yedNS${*9?4z1;3Y;9@bIC%BV=jQ$g zaV00DcYID4Z&wcQ;ZPI4-81jq&e8?f{KDt1+I5#>yM|lO%+fPCygw4t+z(hjU|MWp zvHzJ?;Wn-<-K&D9rE>pZi0R1rSN^aq?b`fVv#RR!Kb?JJTA=nwa{Fcf#-;TW@B4Oj z*2rDveZAN${>kSTvgUgpw}h<@)heqvb@*uJ?z_*veX9?9^Wnsop&rY(z%GDAk#SEJyNrxX#s2&2ds D^k_V0fm9UVQ@(A-@7pO3Jh zBfsq5 w#}H+87*6O`SsdGq7y>gwdfj~*rcFgEpKFlu0NV5%_TEMoZRqS16h z_!WangZpF!b^-qur4E~gd{`wXl(W24GC#y(;TbN;w`hAqP2q~uHl6#=6mMml{b1%J z-y(--aVufRf9qFs&%MkrKWhW;JmE8M{+^xtDK&E2CD+dv?Yn9UF1;*Sv%~iC<;(ga zt~RVcogajLT)uN(d|gB{??=v~7tUPk3S`#N?5p7U z#N}s^`seq?FK4i \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index 77053960..00000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/window.svg b/public/window.svg deleted file mode 100644 index b2b2a44f..00000000 --- a/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/sections-functions.md b/sections-functions.md deleted file mode 100644 index ff30c5be..00000000 --- a/sections-functions.md +++ /dev/null @@ -1,829 +0,0 @@ -# Företagsmoduler — Funktionskatalog per bransch - -Varje bransch har fyra lager: - -- **Bokföring & Skatt** — Branschanpassade BAS-kontoplan, momsinställningar, skatteregler och auto-kontosättning -- **Branschrapporter** — KPI:er och analysverktyg specifika för sektorn -- **Smart import** — Filimport (CSV/Excel/SIE) från branschens vanliga system med automatisk bokföring -- **Operativa moduler** — Verksamhetsstöd som kan, men inte måste, koppla till bokföringen - -Modulantal varierar per bransch beroende på verklig bokföringskomplexitet. - ---- - -## 1. Restaurang & Café - -En av de mest bokföringskrävande branscherna. Blandad moms (12% mat, 25% alkohol/dryck), dagskassaavstämning, personalliggare, drickshantering och representation skapar många unika behov. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Restaurangkontoplan** | BAS-kontoplan förberedd för restaurang med uppdelning per intäktstyp | Separata konton för mat (3001), dryck (3002), alkohol (3003), take-away; auto-kontosättning från kassaimport | -| **Momssplit mat/dryck** | Automatisk uppdelning av moms 12% (mat) vs 25% (alkohol, dryck) | Regelmotor för momsfördelning, hantering av blandade kvitton, månadsavstämning per momssats | -| **Dagskassaavstämning** | Stäm av kassans Z-rapport mot faktisk kassa och bank | Z-rapport-import, avvikelseanalys (svinn, differens), verifikation per dag | -| **Tipsbokföring** | Bokför dricks korrekt — arbetsgivaravgift på kartdricks, skattefri kontantdricks | Fördelning per anställd, arbetsgivaravgiftsberäkning, konto 7699/7010-koppling | -| **Personalliggare** | Elektronisk personalliggare enligt krav från Skatteverket | Daglig registrering in/ut, exportformat för kontroll, koppla till lönekostnad | -| **Alkoholpunktskatt** | Hantera punktskatt vid egenbrygd/import av alkohol | Accisberäkning, lagerrapportering, Tullverket-format | -| **Representationsbokföring** | Bokför representation med rätt avdragsgränser | Automatisk split avdragsgill/ej avdragsgill del, 90 SEK-gräns internt, momsavdrag | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Matkostnad (Food Cost %)** | Livsmedelskostnad som andel av matintäkt | Daglig/veckovis/månadsvis %, mål vs utfall, trendkurva, larmgräns | -| **Personalkostnad vs omsättning** | Spåra personalkostnad som andel av total omsättning | Målvärde (typiskt 30-35%), trend, jämförelse budget | -| **Svinnrapport** | Analysera matsvinn i kronor och procent | Svinn per kategori, kostnad, svinn-till-omsättning | -| **RevPASH** | Revenue per available seat hour | Intäkt per stolstimme, jämförelse per pass (lunch/middag), kapacitetsoptimering | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Z-rapport-import** | Importera dagskassarapport från kassasystem | CSV/Excel från iZettle, Trivec, Square, Orderbird; auto-bokför med momssplit och kontosättning | -| **Leverantörsfaktura-import** | Importera leverantörsfakturor för matinköp | Parsning av leverantörsformat (Martin & Servera, Menigo), kostnadsfördelning per kategori | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Menyhantering** | Bygg och publicera menyer digitalt | Menybyggare, säsongsbyte, allergenmarkering, prissättning per kanal | -| **Bordsbokning** | Online och manuell bordsreservation | Bokningswidget, no-show-hantering, sittningsplanering, kapacitetsvy | -| **Receptkalkyl** | Beräkna kostnad per rätt utifrån inköpspriser | Receptbyggare, portionskostnad, marginalkalkyl, prisändringsanalys | -| **Personalschema** | Schemalägg personal i skift | Skiftplanering, bytesförfrågningar, övertidsvarning, tillgänglighetsvy | -| **Leverantörsbeställning** | Beställ varor direkt till leverantörer | Beställningsmallar, leveransbevakning, prishistorik | - ---- - -## 2. Hotell & Boende - -Moms 12% på boende, 25% på övriga tjänster. Förskottsbetalningar, channel manager-provisioner, säsongsprissättning och nattrevision skapar unik bokföringskomplexitet. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Hotellkontoplan** | BAS-konton uppdelade per intäktstyp: rum, konferens, F&B, tilläggstjänster | Konton 3010 (rumsintäkter), 3020 (konferens), 3030 (F&B); auto-kontosättning | -| **Momssplit boende/tjänst** | Moms 12% på boende, 25% på frukost, minibar, spa, parkering | Automatisk split vid kombinationspaket (halvpension, konferenspaket), momsavstämning | -| **Förskottsbetalning** | Bokför förskott/depositioner korrekt som förutbetald intäkt | Konto 2420, automatisk intäktsföring vid incheckning, avbokningsbokföring | -| **Provisionshantering** | Bokför provision till Booking.com, Expedia, Airbnb som kostnad | Provisionsberäkning per kanal, nettointäkt per bokning, konto 6090 | -| **Nattrevision** | Automatiserad nattlig avstämning av dagens intäkter | Dagsbokslut, kassaavstämning, no-show-debitering, verifikation per dygn | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **RevPAR** | Revenue per available room — branschens viktigaste KPI | Beläggningsgrad × ADR, jämförelse per månad/säsong, budget vs utfall | -| **ADR (Average Daily Rate)** | Genomsnittlig rumspris | Pris per rumstyp, kanalfördelning, säsongsanalys | -| **Beläggningsgrad** | Procent uthyrda rum | Daglig/veckovis/månadsvis, prognos baserad på bokningsläge | -| **Kanallönsamhet** | Jämför nettointäkt per kanal efter provision | Direktbokning vs OTA, provision %, rekommendation | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **PMS-import** | Importera boknings- och intäktsdata från PMS (Mews, Protel, Hotellinx) | CSV/Excel, nattrevisionsrapport, auto-bokföring med momssplit | -| **Channel Manager-rapport** | Importera provisionssammanställning per kanal | Booking/Expedia/Airbnb-rapporter, provisionsbokföring | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Rumsbokning** | Central bokningsmotor | Kalendervy, tillgänglighet, säsongspriser, min/max-nätter | -| **Gästregister** | Gästprofiler och historik | Kontaktuppgifter, besökshistorik, preferenser, GDPR | -| **Städschema** | Planera städning per rum | Status per rum, checklista, personalfördelning | -| **Säsongsplanering** | Priser och kapacitet per säsong | Säsongsdefinition, dynamisk prissättning, beläggningsprognos | -| **Gästkommunikation** | Automatiska meddelanden | Bekräftelse, incheckning, utcheckning, recensionsförfrågan | - ---- - -## 3. Tech & IT - -Tidrapportering som styr fakturering. Projektredovisning med WIP (Work in Progress). FoU-avdrag. Licensavskrivningar. Relativt enkel moms (25% tjänst, omvänd moms vid EU-försäljning). - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **IT-kontoplan** | BAS-konton anpassade för konsult/SaaS-bolag | Konton för konsultintäkter, licensintäkter, SaaS MRR; auto-kontosättning | -| **Projektredovisning** | Intäkter och kostnader per kundprojekt | Successiv vinstavräkning, WIP-beräkning (konto 1470), projektbokslut | -| **FoU-avdrag** | Beräkna avdrag för forskning och utveckling | Nedsättning av arbetsgivaravgifter, underlag per anställd, Skatteverket-krav | -| **Licensavskrivning** | Hantera avskrivning av mjukvarulicenser och IP | Avskrivningsplan, konto 1010/1020, linjär vs degressiv avskrivning | -| **EU-tjänstemoms** | Omvänd skattskyldighet vid försäljning till EU-kunder | Automatisk B2B-kontroll (VAT-nummer), konto 2614, EU-försäljningsrapport | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Debiteringsgrad** | Andel debiterbara timmar av total arbetstid | Per konsult/team, mål vs utfall, trend | -| **Projektlönsamhet** | Intäkt minus kostnad per projekt | Timkostnad vs debiterat, överdrag-varning, jämförelse budget | -| **MRR/ARR** | Monthly/Annual Recurring Revenue för SaaS | Tillväxttakt, churn, expansion revenue | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Tidrapport-import** | Importera tidrapporter från Harvest, Toggl, Clockify | CSV/Excel, auto-koppling till projekt, fakturaunderlag | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Projekthantering** | Överblick och styrning av kundprojekt | Projekttavla, milstolpar, tidslinje, budgetuppföljning | -| **Tidrapportering** | Logga tid per projekt och kund | Timer, manuell inmatning, godkännandeflöde, debiterbara timmar | -| **Ärendehantering** | Supportärenden och buggspårning | Ärendekö, SLA-prioritet, statusflöde, kundportal | -| **Resursplanering** | Allokera personal till projekt | Beläggningsvy, kompetensfilter, överlappningsvarning | - ---- - -## 4. Bygg & Entreprenad - -Komplex bransch: omvänd skattskyldighet (moms) inom byggsektorn, ROT-avdrag, successiv vinstavräkning per projekt, ÄTA-hantering, UE-attestering och personalliggare. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Byggkontoplan** | BAS-konton med projektkontosättning och UE-konton | Separata konton per projekt, UE-kostnader (konto 4400), materialkostnader | -| **Omvänd skattskyldighet bygg** | Automatisk hantering av omvänd moms (6 kap. ML) vid UE-tjänster | Automatisk kontroll köpare/säljare, fakturamärkning, momsdeklaration ruta 24 | -| **ROT-avdrag** | Beräkna och rapportera ROT-avdrag per kund | Automatisk 30%-beräkning, maxbelopp 50 000 SEK, personnummervalidering, Skatteverket-format | -| **Successiv vinstavräkning** | Periodisera projektintäkter efter färdigställandegrad | Beräkning av färdigställandegrad, intäktsperiodisering, konto 1470 WIP | -| **UE-attestering** | Attestflöde för underentreprenörsfakturor | Godkännandeflöde, delavstämning, F-skatt-kontroll, försäkringsverifiering | -| **Personalliggare** | Elektronisk personalliggare enligt Skatteverkets krav | In/ut-registrering, export vid kontroll, UE-personal inkluderad | -| **ÄTA-bokföring** | Koppla ÄTA-arbeten till rätt projekt och faktura | ÄTA-registrering, kostnadseffekt på projektkalkyl, intäktsökning vid godkänd ÄTA | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Projektmarginal** | Kalkylerad vs verklig marginal per projekt | Budget vs utfall, ÄTA-påverkan, UE-kostnad vs plan | -| **ÄTA-analys** | ÄTA som andel av ursprunglig kalkyl | ÄTA-andel per projekt, typ av ÄTA, kundgodkännandestatus | -| **Likviditet per projekt** | Kassaflöde per projekt — fakturerat vs betalt vs kostnad | Faktureringsrytm, kundfordringsålder, UE-skulder | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **UE-fakturaimport** | Importera underentreprenörsfakturor | Parsning, projektkoppling, F-skatt-kontroll, auto-kontosättning | -| **Materialkostnadsimport** | Importera materialinköp per projekt | Leverantörsformat (Beijer, Ahlsell), projektfördelning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Projektkalkyl** | Detaljerade kalkyler inför anbud | Arbete, material, maskiner, UE-kostnader, marginalpåslag | -| **ÄTA-hantering** | Spåra ändringar, tillägg och avgående | Registrering, kundgodkännande, koppling till faktura | -| **Byggdagbok** | Digital dagbok per projekt | Dagliga noteringar, foto, väderpåverkan, personallog | -| **Ritningshantering** | Versionshantering av projektritningar | Uppladdning, versionsjämförelse, distribution till UE | -| **Materialbeställning** | Beställ och spåra material | Materiallistor, leveransbevakning, kostnadsuppföljning | - ---- - -## 5. Hälsa & Sjukvård - -Sjukvårdstjänster är momsfria (3 kap. 4-5 § ML) men kompletterande tjänster (friskvård, kosmetisk) kan vara momspliktiga. Blandning av regionavtal, privata patienter och försäkringsersättningar. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Vårdkontoplan** | BAS-konton uppdelade per intäktstyp: regionavtal, privatpatienter, försäkring | Konton 3010 (regionersättning), 3020 (patientavgift), 3030 (försäkring) | -| **Momsfrihet sjukvård** | Hantera momsfria vårdtjänster vs momspliktiga sidotjänster | Automatisk momsbedömning per tjänsttyp, korrekt moms vid blandad verksamhet | -| **Försäkringsersättning** | Bokför ersättningar från försäkringsbolag korrekt | Intäktsföring vid godkännande, kundfordran per försäkringsbolag, avskrivning av nekade ärenden | -| **Frikort & Högkostnadsskydd** | Hantera patienters frikort vid avgiftsberäkning | Automatisk kontroll mot högkostnadsgräns, rapportering till region | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Intäkt per behandlare** | Omsättning fördelat per vårdgivare | Per dag/vecka/månad, privatpatienter vs region, besökssnitt | -| **Patientmix** | Fördelning region/privat/försäkring | Intäktsfördelning per betalarkategori, trend, lönsamhet per typ | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Regionersättningsimport** | Importera utbetalningsbesked från region | Periodisering, kontosättning, avstämning mot avtal | -| **Försäkringsrapport-import** | Importera beslut och utbetalningar från försäkringsbolag | Auto-bokföring godkända/nekade ärenden | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Patientbokning** | Bokning av besök och behandlingar | Onlinebokning, kalendervy, SMS-påminnelse, väntelista | -| **Journalhantering** | Strukturerade patientjournaler | Anteckningar, diagnoser, vårdplan, GDPR-efterlevnad | -| **Remisshantering** | Skicka och ta emot remisser | Mallar, statusspårning, svarsbevakning | -| **Kassasystem & Patientavgifter** | Debitera patientbetalningar | Avgiftskategorier, frikort-koll, kortbetalning | - ---- - -## 6. Detaljhandel - -Lagervärdering (FIFO/vägt genomsnitt) påverkar bokslut direkt. Kassaavstämning dagligen. Moms 25% standard men 6%/12% på vissa varor. Svinn påverkar lagerresultat. Personalliggare i livsmedelsbutik. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Detaljhandelskontoplan** | BAS-konton per produktkategori och momssats | Intäktskonton per varugrupp, separata konton 25%/12%/6% moms | -| **Lagervärdering** | Löpande beräkning av lagervärde för bokslut | FIFO och vägt genomsnitt, månadsbokslut, inkuransbedömning, konto 1400 | -| **Kassaavstämning** | Daglig avstämning kassa vs kassarapport | Z-rapport-import, avvikelse, kontant/kort-split, verifikation per dag | -| **Svinnbokföring** | Bokför varusvinn korrekt som kostnad | Svinnregistrering, konto 4730, period-uppföljning | -| **Personalliggare** | Elektronisk personalliggare (obligatorisk livsmedelsbutik) | In/ut-registrering, Skatteverket-export | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Bruttomarginal per varugrupp** | Inpris vs utpris per kategori | Marginal %, jämförelse kampanjperiod vs normal, trendvy | -| **Lageromsättningshastighet** | Hur snabbt lagret omsätts | Per varugrupp, kapitalbindning, beställningspunkt-förslag | -| **Svinnprocent** | Svinn i kronor och procent av omsättning | Per kategori, trend, benchmark mot branschsnitt | -| **Försäljning per m²** | Butikseffektivitet | Intäkt per kvadratmeter, jämförelse butiker | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **POS Z-rapport-import** | Dagskassarapport från kassasystem | CSV/Excel från iZettle, Sitoo, Caspeco; auto-kontosättning med momssplit | -| **Inventeringsimport** | Importera inventeringsresultat | Avvikelseberäkning, lageruppdatering, svinnbokföring | -| **Leverantörsfaktura-import** | Importera leverantörsfakturor | Parsning, inprisuppdatering, auto-kontosättning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Lagerhantering** | Lagernivåer och rörelser | Inleverans, bristlista, beställningspunkt, lagerplatser | -| **Kampanjer & Rabatter** | Priskampanjer och erbjudanden | Rabattregler, tidsbegränsade kampanjer, marginalbevakning | -| **Kundklubb** | Lojalitetsprogram | Poängintjäning, belöningar, riktade kampanjer | -| **Prishantering** | Centraliserad prissättning | Inpris vs utpris, marginalkalkyl, prisändringslogg | -| **Butiksdrift & Schema** | Bemanning och öppettider | Schemaläggning, timrapport, budgetjämförelse | - ---- - -## 7. E-handel - -Plattformsimport (Shopify, Woo) → auto-bokföring. Returer som kreditering. Multi-currency med kursdifferens. EU-moms via OSS. Lagervärdering. Fraktbokföring. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **E-handelskontoplan** | BAS-konton för orderintäkter, fraktintäkt, returer, plattformsavgifter | Konton 3001 (varuförsäljning), 3540 (fraktintäkt), 3740 (returkostnad), 6590 (plattformsavgift) | -| **Lagervärdering** | Löpande lagervärde för bokslut | FIFO, vägt genomsnitt, månadsbokslut, inkuransbedömning | -| **Returbokföring** | Automatisk kreditering vid returer | Lageråterföring, konto 3740, momskorrigering, periodsummering | -| **Multi-currency** | Bokför försäljning i utländsk valuta i SEK | Valutaomvandling via Riksbanken-kurs, kursdifferens konto 3960/7960 | -| **EU-moms (OSS)** | One Stop Shop för moms vid EU-distansförsäljning | Moms per destinationsland, OSS-deklarationsunderlag, tröskelvärdebevakning | -| **Plattformsavgifter** | Bokför avgifter från Shopify, Stripe, Klarna korrekt | Bruttoförsäljning → avgift → nettoutbetalning, periodisering | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Returprocent** | Returer som andel av försäljning | Per produktkategori, kostnad per retur, trend | -| **Genomsnittligt ordervärde (AOV)** | Snittorder i kronor | Trend, kanalfördelning, kampanjeffekt | -| **Kanalfördelning** | Intäkt per försäljningskanal | Egen webb vs marknadsplats, marginal per kanal | -| **Fraktkostnad vs intäkt** | Fraktnetto per order | Fraktsubvention, break-even-analys | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Shopify/Woo-import** | Importera ordrar och utbetalningsrapporter | CSV-export, auto-bokföring per order inkl. moms, frakt, rabatter | -| **Klarna-rapport-import** | Importera Klarna-utbetalningar och avgifter | Bruttobelopp, avgiftsavdrag, nettoutbetalning, periodmatchning | -| **Fraktrapport-import** | Importera fraktkostnader per order | Postnord/DHL/Budbee-rapporter, kostnadsfördelning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Orderhantering** | Central ordervy | Orderstatus, plocklista, batch-hantering | -| **Frakthantering** | Hantera frakt | Fraktsedlar, spårning, returlogistik | -| **Returhantering** | Hantera returer och byten | Returgodkännande, lageråterföring, återbetalning | -| **Produktdatahantering** | Central produktinfo | Beskrivningar, bilder, attribut | - ---- - -## 8. Frisör & Skönhet - -Provisionsberäkning som lönekostnad. Presentkort som förutbetald intäkt. Moms 25% på allt (tjänst + vara). Personalliggare obligatorisk. Kassaavstämning dagligen. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Salongkontoplan** | BAS-konton uppdelade: tjänsteintäkter, produktförsäljning, presentkort | Konton 3010 (behandling), 3020 (produktförsäljning), 2420 (presentkortsskuld) | -| **Provisionsberäkning** | Räkna provision per frisör/terapeut och bokför som lönekostnad | Procent på tjänst/produkt, trappsteg, konto 7010/7210, månadssammanställning | -| **Presentkort som skuld** | Bokför sålda presentkort som förutbetald intäkt tills inlösen | Konto 2420 (skuld), intäktsföring vid inlösen, förfallohantering | -| **Kassaavstämning** | Daglig avstämning kort/Swish/kontant | Z-rapport, avvikelse, verifikation per dag | -| **Personalliggare** | Elektronisk personalliggare enligt Skatteverket | In/ut-registrering, export vid kontroll | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Intäkt per stol** | Omsättning per arbetsstation | Per dag/vecka, beläggningsgrad, optimeringsförslag | -| **Provisionsandel** | Provisionskostnad som andel av tjänsteintäkt | Per frisör, trend, lönsamhet per anställd | -| **Produktförsäljning per besök** | Merförsäljning av produkter | Snitt per kund, andel av omsättning | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Kassarapport-import** | Importera dagskassa från kassasystem | CSV från iZettle/Zettle, auto-kontosättning | -| **Bokningssystem-import** | Importera bokningsdata och intäkter | Export från Timma, Fresha, Planway; intäktsfördelning per behandlare | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Tidsbokning** | Online och receptionsbokning | Bokningswidget, SMS-påminnelse, väntelista | -| **Kundkort** | Profil med behandlingshistorik | Favoritbehandlare, allergier, färgrecept | -| **SMS-påminnelser** | Automatiska påminnelser | Bokningspåminnelse, återbesökspåminnelse | -| **Skiftschema** | Schemalägg personal | Stolsfördelning, ledighetsönskemål | - ---- - -## 9. Transport & Logistik - -Fordonsavskrivningar, leasing, bränslekostnad per fordon, milersättning vs faktisk kostnad. Trängselskatt. Cabotageregler vid internationell transport. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Transportkontoplan** | BAS-konton per kostnadskategori: bränsle, leasing, underhåll, försäkring | Konton per fordon möjligt, kostnadskonton 5610/5620/5611/5612 | -| **Fordonsavskrivning** | Hantera avskrivning per fordon | Linjär/degressiv, räkenskapsenlig avskrivning, konto 1240/7832 | -| **Leasinghantering** | Bokför leasing korrekt (operationell vs finansiell) | Leasingavgift som driftskostnad, restvärde, avtalsperiod | -| **Trängselskatt** | Bokför trängselskatt som avdragsgill kostnad | Auto-kontosättning konto 5615, per fordon, periodsammanställning | -| **Milersättning vs faktisk kostnad** | Jämför schablon (25 kr/mil) mot verklig fordonskostnad | Per fordon, rekommendation avdragsmetod, Skatteverket-schabloner | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Kostnad per mil** | Total driftskostnad per mil och per fordon | Bränsle + underhåll + avskrivning + försäkring, trend | -| **Intäkt per fordon** | Omsättning fördelad per fordon | Lönsamhet per fordon, underutnyttjade resurser | -| **Bränsleeffektivitet** | Bränsleförbrukning per fordon och period | Liter/mil, trend, avvikelse mot förväntat | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Bränslekort-import** | Importera tankningar från bränslekort (Circle K, OKQ8, Preem) | CSV, auto-kontosättning per fordon | -| **Vägtulls-import** | Importera trängselskatt och broavgifter | Transportstyrelsen-format, auto-kontosättning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Flottahantering** | Fordonsregister och översikt | Besiktning, försäkring, leasingperioder | -| **Ruttplanering** | Optimera körrutter | Adressklustring, tidsestimering, kapacitet | -| **Leveransspårning** | Realtidsspårning av leveranser | GPS, ETA, leveransbevis, kundnotifiering | -| **Fordonsunderhåll** | Planera service och reparationer | Serviceintervall, reservdelshistorik | -| **Chaufförshantering** | Personal och behörigheter | Körkortsklass, YKB, timrapport | -| **Fraktsedlar & Dokument** | Generera fraktdokument | CMR, följesedel, digital signatur | - ---- - -## 10. Juridik & Redovisning - -Tidrapport → fakturering (löpande räkning). Klientmedelskonto. WIP-värdering. A conto-fakturering. Intressekonflikt påverkar inte bokföringen men är branschkrav. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Juristkontoplan** | BAS-konton för arvodesintäkter, klientmedel, utlägg | Konton 3010 (arvoden), 1690 (klientmedel i förvaltning), 6990 (utlägg för klients räkning) | -| **Klientmedelskonto** | Separat hantering av klientmedel (disciplinnämndsregler) | Konto 1690/2890, klientmedelslista, avstämning mot bankkonto, rapportering | -| **WIP-värdering** | Värdera pågående arbete (nedlagd tid ej fakturerad) | Beräkning av WIP, konto 1470, månatlig omvärdering | -| **A conto-bokföring** | Bokför a conto-fakturor och slutavräkning | Förskottsbokföring konto 2420, avräkning vid slutfaktura | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Debiteringsgrad** | Andel debiterbara timmar av total arbetstid | Per jurist/konsult, mål vs utfall, trend | -| **Realisationsgrad** | Fakturerat belopp vs tidvärde (nedskrivning av tid) | Per ärende, mönsteranalys, lönsamhet per ärendety | -| **Genomsnittlig timintäkt** | Faktiskt fakturerat per timme | Per jurist, klient, ärendetyp; jämförelse mot prislista | -| **WIP-rapport** | Totalt pågående arbete ej fakturerat | Per klient/ärende, åldringsanalys, risk för nedskrivning | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Tidrapport-import** | Importera tid från ärendehanteringssystem | CSV från Time, Clio, Maconomy; koppling till ärende och klient | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Ärendehantering** | Administrera klientärenden | Ärendetyper, statusflöde, deadline-bevakning | -| **Tidrapportering** | Registrera tid per ärende | Debiterbara vs interna timmar, godkännande | -| **Dokumenthantering** | Versionshanterade dokument per ärende | Mallbibliotek, e-signering, klientdelning | -| **Deadlinebevakning** | Påminnelser för tidsfrister | Preskriptionstider, eskaleringsregler | -| **Intressekonfliktskontroll** | Kontrollera jäv vid nya ärenden | Partsregister, automatisk sökning, logg | - ---- - -## 11. Utbildning & Förskola - -Maxtaxa-regler vid fakturering. Kommunala bidrag/peng som intäkt. Momsfri utbildning. Statsbidrag med krav på periodisering. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Utbildningskontoplan** | BAS-konton för kommunal peng, statsbidrag, föräldraavgift | Konton 3010 (kommunal ersättning), 3020 (föräldraavgift), 3910 (statsbidrag) | -| **Maxtaxa-fakturering** | Automatisk beräkning av avgift enligt maxtaxa-reglerna | Inkomstkontroll, syskonrabatt, schema-avdrag, frånvaroavdrag | -| **Statsbidragsperiodisering** | Periodisera statsbidrag korrekt över den period de avser | Konto 2970 (förutbetald intäkt), villkorsuppfyllnad, återbetalningsrisk | -| **Momsfrihet utbildning** | Utbildningstjänster är momsfria | Korrekt momsbedömning, sidoverksamhet (cafeteria, uthyrning) kan vara momspliktig | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Kostnad per barn/elev** | Total driftskostnad per inskrivet barn | Personal, lokal, mat, material; jämförelse med kommunal peng | -| **Personaltäthet** | Antal barn per heltidsanställd | Trend, lagkrav (förskolans riktlinje), schemaanalys | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Kommunal peng-import** | Importera utbetalningsbesked från kommun | Periodisering, kontosättning, avstämning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Schemaläggning** | Undervisningsschema | Per klass/lärare/sal, konfliktkontroll | -| **Elevregister** | Elev- och barnuppgifter | Kontakt, vårdnadshavare, allergi, specialbehov | -| **Närvarohantering** | Registrera frånvaro | Daglig närvaro, mönsteranalys, föräldraavisering | -| **Föräldrakommunikation** | Meddelanden till vårdnadshavare | Push/e-post/SMS, nyhetsflöde | -| **Matsedel & Allergikost** | Publicera matsedel | Veckomatsdel, allergiflaggor | -| **Vikariebokning** | Hantera vikarier | Vikariepool, snabbbokning, kostnadsspårning | - ---- - -## 12. Jordbruk & Livsmedel - -Unik skatteposition: skogskonto, expansionsfond, räntefördelning (EF/NE). EU-stöd som intäkt (periodisering). Biologiska tillgångar. Moms 12% livsmedel vs 25% övriga varor. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Jordbrukskontoplan** | BAS-konton anpassade för gröda, djur, skogsbruk, EU-stöd | Konton 3010 (växtodling), 3020 (djurförsäljning), 3910 (EU-stöd), 1280 (biologiska tillgångar) | -| **Skogskonto** | Hantera insättning och uttag från skogskonto | Insättning (max 60% av skogsintäkt), beskattning vid uttag, konto 1760 | -| **Expansionsfond** | Beräkna avsättning till expansionsfond för enskild firma | Beräkning av underlag, expansionsfondsskatt 20,6%, NE-bilaga | -| **Räntefördelning** | Positiv/negativ räntefördelning på kapital | Kapitalunderlag, statslåneränta, inkomstfördelning tjänst/kapital | -| **EU-stöd som intäkt** | Periodisera EU-jordbruksstöd korrekt | Intäktsföring per period, villkorsskuld, jämförelse ansökt vs utbetalt | -| **Biologiska tillgångar** | Värdera djur och grödor som tillgång | Anskaffningsvärde vs verkligt värde, konto 1280, årlig omvärdering | -| **Momssplit livsmedel** | Moms 12% vid livsmedelsförsäljning, 25% övriga varor | Automatisk momskod per produkttyp | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Avkastning per hektar** | Intäkt minus kostnad per odlad yta | Per gröda, säsongsjämförelse, vädereffekt | -| **Bidragsberoende** | EU-stöd som andel av total intäkt | Trend, risk vid policyändring | -| **Djurkostnad per enhet** | Total kostnad per djur (foder, veterinär, stall) | Per djurtyp, jämförelse med intäkt vid slakt/försäljning | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **SAM-utbetalningsimport** | Importera utbetalningsbesked för EU-jordbruksstöd | Jordbruksverket-format, periodisering, auto-kontosättning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Skördeplanering** | Planera odlingscykler | Fältregister, grödor, sådd/skörd-datum | -| **Djurhållning** | Register och uppföljning av besättning | Individregister, hälsologg, Jordbruksverket-rapportering | -| **Spårbarhet** | Spåra livsmedel från jord till bord | Batchnummer, leveranskedja, återkallning | -| **Maskinlogg** | Drifttid och underhåll | Maskinregister, timlogg, servicepåminnelse | -| **Certifieringar** | KRAV, ekologisk, EU-ekologisk | Certifikatregister, giltighetstid, revisionsförberedelse | - ---- - -## 13. Media & Kommunikation - -Projektredovisning. Freelancer-fakturor (F-skatt-kontroll). Immateriella rättigheter som tillgång. Licensintäkter. Ofta blandad tjänstemoms (25%) och kulturmoms (6%). - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Mediakontoplan** | BAS-konton per intäktstyp: projektarvoden, licensintäkt, royalties | Konton 3010 (projektintäkt), 3020 (licensintäkt), 3910 (royalty) | -| **Projektredovisning** | Intäkter och kostnader per kundprojekt | Budget vs utfall, WIP vid pågående projekt, projektbokslut | -| **Freelancer-bokföring** | Hantera fakturor från frilansare korrekt | F-skatt-kontroll, auto-kontosättning konto 4010, kostnad per projekt | -| **Kulturmoms** | Hantera moms 6% vid publicering, film, kultur | Korrekt momssats per tjänsttyp, blandad verksamhet | -| **IP-tillgångar** | Aktivera och avskriva immateriella rättigheter | Aktivering, avskrivningsplan, konto 1010/1020 | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Projektlönsamhet** | Intäkt minus kostnad per projekt | Budget vs utfall, timkostnad vs debiterat | -| **Freelancerandel** | Andel av produktionskostnad som går till freelancers | Trend, lönsamhetspåverkan, per projekttyp | -| **Kundlönsamhet** | Intäkt och marginal per kund | Tidsförbrukning vs fakturerat, återkommande kunder | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Freelancer-fakturaimport** | Importera fakturor från frilansare | Parsning, F-skatt-verifiering, projektkoppling | -| **Kampanjrapport-import** | Importera kampanjresultat | Intäkter per kampanj, provisionskostnader | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Projekthantering** | Styra kundprojekt | Projekttavla, tidslinje, kundgodkännande | -| **Innehållsplanering** | Redaktionskalender | Kanalvy, statusflöde, deadlines | -| **Mediebank** | Central lagring av media | Taggning, sök, rättighetsspårning | -| **Tidrapport & Debitering** | Logga tid per kund | Timer, budget vs utfall, fakturaunderlag | - ---- - -## 14. Fitness & Sport - -Autogiro-intäkter (periodisering). Klippkort/förskott som skuld. Moms 6% på idrott, 25% på PT och spa. Friskvårdsbidragsproblematik. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Fitnesskontoplan** | BAS-konton per intäktstyp: medlemskap, PT, klippkort, shop | Konton 3010 (medlemsavgift), 3020 (PT), 2420 (klippkortsskuld), 3030 (shop) | -| **Momssplit idrott/PT** | Moms 6% på idrottslig verksamhet, 25% på PT, spa, shop | Automatisk momssats per tjänsttyp, blandad verksamhet | -| **Autogiro-periodisering** | Bokför autogiro-dragningar som intäkt rätt period | Förskottsbetalning, periodisering konto 2970, misslyckade dragningar | -| **Klippkort som skuld** | Sålda klippkort/startpaket bokförs som förutbetald intäkt | Konto 2420, intäktsföring per nyttjat tillfälle, förfallohantering | -| **Friskvårdsbidrag** | Hantera friskvårdsbidrag från arbetsgivare | Skatteverkets gräns (5 000 SEK), kvittogenerering, dokumentation | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Churn rate** | Medlemsavgång per månad | Trend, orsaksanalys, retention per avtalstyp | -| **Intäkt per medlem** | Genomsnittlig intäkt per aktiv medlem | Inklusive PT, shop, extra tjänster | -| **Beläggningsgrad klasser** | Fyllnadsgrad per gruppträningspass | Per klass/tid, optimering av schema | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Autogiro-rapport-import** | Importera autogiro-dragningsrapport (Bankgirot) | Lyckade/misslyckade, auto-kontosättning, period-matchning | -| **Kassarapport-import** | Importera dagskassa | Drop-in, PT-paket, shop; auto-kontosättning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Medlemshantering** | Registrera och hantera medlemskap | Avtalstyper, förnyelse, uppsägning | -| **Klassbokning** | Boka platser i träningspass | Schema, platsbegränsning, väntelista | -| **PT-bokning** | Boka personlig tränare | Paket, kundhistorik, kalender | -| **Tillträdeskontroll** | Inpassering till anläggning | Nyckelbricka/QR, besökslogg | - ---- - -## 15. Fordon & Verkstad - -Arbetsorder → faktura. Reservdelslager (lagervärdering). Garanti-avsättningar. VMB (vinstmarginalbeskattning) vid begagnade delar. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Verkstadskontoplan** | BAS-konton per intäktstyp: arbete, reservdelar, besiktning | Konton 3010 (arbetsintäkt), 3020 (reservdelar), 4010 (inköp reservdelar) | -| **Arbetsorder → Faktura** | Generera faktura direkt från arbetsorder | Timpris + delar, automatisk summering, konto-koppling | -| **Reservdelslager** | Lagervärdering av reservdelar | FIFO, konto 1460, månadsbokslut, inkuransavdrag | -| **VMB (begagnade delar)** | Vinstmarginalbeskattning vid försäljning av begagnade reservdelar | Beräkning av vinstmarginal, moms enbart på marginalen, konto 2640 | -| **Garantiavsättning** | Avsätt för framtida garantikostnader | Avsättning konto 2290, upplösning vid faktisk kostnad | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Genomsnittligt ordervärde** | Snittfaktura per arbetsorder | Arbete vs delar, trend, kundtypsanalys | -| **Reservdelsmarginal** | Inpris vs utpris på delar | Per kategori, trend | -| **Verkstadsbeläggning** | Utnyttjandegrad av lyftar och mekaniker | Per resurs, optimering | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Reservdelsleverantör-import** | Importera priser och leveranser | Mekonomen, Autoexperten-format, auto-kontosättning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Arbetsorder** | Skapa och hantera arbeten | Registrering, mekaniker-tilldelning, statusflöde | -| **Fordonsregister** | Register med fordonshistorik | Regnummer, servicehistorik, besiktningsdatum | -| **Verkstadsplanering** | Beläggning av lyftar och personal | Kalendervy, bokningstider, akut-slot | -| **Besiktningspåminnelse** | Automatiska påminnelser | SMS/e-post, historik | - ---- - -## 16. Bemanning & HR - -Tidrapport → kundfaktura + löneunderlag (dubbelt flöde). Marginalberäkning per uppdrag. Socialavgiftsperiodisering. F-skatt-verifiering av underkonsulter. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Bemanningskontoplan** | BAS-konton per intäkts- och kostnadstyp: uthyrning, rekrytering, underkonsulter | Konton 3010 (uthyrningsintäkt), 3020 (rekryteringsarvode), 4010 (UE-kostnad), 7010 (löner) | -| **Tidrapport → Dubbelbokföring** | Tidrapport genererar både kundfaktura och löneunderlag | Timrapport, kunddebitering, lönekostnad, marginalberäkning per uppdrag | -| **Arbetsgivaravgifter-periodisering** | Periodisera arbetsgivaravgifter korrekt per månad | Beräkning per anställd, konto 7510, semesterlöneskuld, period-vy | -| **UE-verifiering** | Kontrollera F-skatt och försäkring för underkonsulter | Skatteverkets API-kontroll, dokumentation, fakturamottagning | -| **Traktamente vid uthyrning** | Beräkna traktamente för uthyrd personal | Skatteverkets schabloner, skattefri del, förmånsbeskattning vid övernattning | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Marginal per konsult** | Debiterat minus lönekostnad per uthyrd person | Per uppdrag, trend, jämförelse | -| **Beläggningsgrad** | Andel uthyrd tid av total tid | Per konsult, team, totalt | -| **Fakturerat per konsult** | Total fakturering per person och period | Ranking, budget vs utfall | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Tidrapport-import** | Importera timmar från kundsystem | CSV, kundgodkännande-status, auto-koppling till uppdrag | -| **Lönesystem-import** | Importera löneunderlag | Export från Hogia, Visma Lön; auto-bokföring av lön + sociala avgifter | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Kandidatregister** | Rekryteringsdatabas | CV, kompetens, status, GDPR-rensning | -| **Uppdragshantering** | Matcha kandidater med uppdrag | Kravprofil, matchning, förlängning | -| **Avtalshantering** | Kundavtal och konsultavtal | Templates, förnyelsepåminnelser | -| **Kompetensregister** | Certifieringar och utbildningar | Per person, giltighetstid | -| **Compliance** | Lagar och branschkrav | ID06-kontroll, arbetstillstånd | - ---- - -## 17. Tillverkning & Industri - -BOM-kalkyl kopplat till lagervärdering. Tre lagernivåer (råvara/halvfabrikat/färdigvara). Produktionsavvikelse bokförs. Maskinavskrivningar. Energiskatteavdrag vid industriprocess. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Tillverkningskontoplan** | BAS-konton per lagertyp och kostnadsställe | Konton 1410 (råvarulager), 1420 (PIA), 1450 (färdigvarulager), 4010 (materialinköp) | -| **Trestegslagervärdering** | Värdera råvaror, halvfabrikat (PIA) och färdigvaror separat | FIFO per lagernivå, omvärdering vid produktion, konto 1410/1420/1450 | -| **BOM-kalkyl → Lagervärde** | Strukturlista (BOM) styr självkostnad per tillverkad enhet | Materialkomponenter, arbetskostnad, OH-pålägg, lagervärde per BOM | -| **Produktionsavvikelse** | Bokför avvikelse mellan kalkylerad och faktisk kostnad | Standard- vs verklig kostnad, avvikelsekonto 4900 | -| **Maskinavskrivning** | Avskrivningsplan för produktionsutrustning | Räkenskapsenlig avskrivning, konto 1210/7831, restvärdeavskrivning | -| **Energiskatteavdrag** | Avdrag för energiskatt vid industriell tillverkning | Nedsättning av energiskatt, ansökan till Skatteverket, periodisering | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Materialeffektivitet** | Faktisk materialförbrukning vs BOM-kalkyl | Spill %, kostnad för avvikelse, trend | -| **Kostnad per producerad enhet** | Total kostnad (material + arbete + OH) per enhet | Per produkt, period-jämförelse | -| **OEE (Overall Equipment Effectiveness)** | Maskinutnyttjandegrad | Tillgänglighet × prestanda × kvalitet | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Produktionsrapport-import** | Importera utfallsdata per tillverkningsorder | Godkänt/kasserat, materialförbrukning, auto-kontosättning | -| **Lagerexport-import** | Importera lagerförändringar | Per lagernivå, inventeringsresultat | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Produktionsplanering** | Schemalägga tillverkningsorder | Ordervy, maskinbeläggning, kapacitet | -| **Strukturlista (BOM)** | Definiera materialstruktur | Komponenter, nivåer, alternativa delar | -| **Kvalitetskontroll** | Säkerställ produktkvalitet | Kontrollplaner, mätprotokoll, avvikelser | -| **Maskinunderhåll** | Förebyggande och avhjälpande underhåll | Schema, felanmälan, reservdelsförbrukning | -| **Spårbarhet & Batch** | Spåra råvaror till färdig produkt | Batchnummer, komponentspårning, återkallning | - ---- - -## 18. Konsult & Rådgivning - -Enklare bokföring: tidrapport → faktura, traktamente, hemmakontor. Ofta enskild firma. WIP-bevakning vid löpande räkning. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Konsultkontoplan** | BAS-konton för konsultintäkt, utlägg, resor | Konton 3010 (konsultarvode), 5800 (resekostnad), 6990 (vidarefakturerade utlägg) | -| **Traktamente** | Beräkna traktamente vid tjänsteresor enligt Skatteverkets schabloner | Hel/halvdag, reducering vid fri måltid, skattefri del, förmånsvärde | -| **Hemmakontor-avdrag** | Schablonavdrag för hemmakontor | Fast belopp (2 000/4 000 SEK), alternativt verklig kostnad med yta-beräkning | -| **WIP-bevakning** | Pågående ej fakturerat arbete | Konto 1470, per uppdrag, åldringsanalys | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Debiteringsgrad** | Debiterbara timmar / total arbetstid | Mål vs utfall, trend | -| **Intäkt per konsult** | Total fakturering per person | Ranking, budget vs utfall | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Tidrapport-import** | Importera tid från Harvest, Toggl, Clockify | CSV, koppling till uppdrag, fakturaunderlag | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Uppdragshantering** | Administrera kunduppdrag | Milstolpar, statusvy, lönsamhetsanalys | -| **Tidrapportering** | Detaljerad tidregistrering | Timer, kategorier, veckoöversikt | -| **Offert & Avtal** | Skapa offerter | Mallar, godkännande, avtalsstatus | - ---- - -## 19. Event & Underhållning - -Biljettintäkter som förskott (periodisering). Moms 6% på kulturella evenemang. SINK-skatt vid utländska artister. Sponsorintäkter. Eventbudget. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Eventkontoplan** | BAS-konton per intäktstyp: biljetter, sponsring, F&B, merch | Konton 3010 (biljettintäkt), 3020 (sponsorintäkt), 3030 (F&B), 3040 (merch) | -| **Biljettintäkt som förskott** | Bokför förskottssålda biljetter som skuld tills eventet äger rum | Konto 2420, intäktsföring vid genomfört event, avbokningshantering | -| **Kulturmoms 6%** | Hantera reducerad moms på kulturella föreställningar | Moms 6% på biljetter, 25% på mat/dryck/merch, blandad verksamhet | -| **Artistskatt (SINK)** | Hantera källskatt för utländska artister | Beräkning av SINK (15%), inbetalning till Skatteverket, underlag per artist | -| **Sponsorintäktsbokföring** | Bokför sponsoravtal med motprestationsperiodisering | Periodisering per event, konto 3910, avtalsvärde vs motprestation | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Intäkt per besökare** | Total intäkt delat på antal besökare | Biljett + F&B + merch, jämförelse mellan event | -| **Budget vs utfall** | Eventbudget jämfört med verkligt resultat | Per kostnadspost, totalt, vinstmarginal | -| **Sponsorandel** | Sponsorintäkt som andel av total intäkt | Per event, trend, beroendeanalys | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Biljettsystem-import** | Importera försäljningsdata från biljettsystem | Ticketmaster, Eventbrite, NORTIC; auto-kontosättning inkl avgifter | -| **POS-rapport-import** | Importera F&B- och merch-försäljning | Kassarapport från eventbar/shop, momssplit | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Evenemangsplanering** | Planera och koordinera event | Checklista, tidslinje, budget | -| **Biljettförsäljning** | Sälj och hantera biljetter | Biljettyper, priskategorier, QR-validering | -| **Artist- & Talangbokning** | Boka artister och föreläsare | Kontrakt, riderhantering, schema | -| **Sponsorhantering** | Hantera sponsoravtal | Avtalsnivåer, motprestationer, uppföljning | -| **Volontärhantering** | Koordinera frivilliga | Registrering, skifttilldelning, kommunikation | - ---- - -## 20. Fastighetsförvaltning - -Hyresintäkter (periodisering). Fastighetsskatt/avgift. Avskrivning fastigheter (lång tid). Underhållsfond. ROT vid renovering. Stämpelskatt vid köp. - -### Bokföring & Skatt - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Fastighetskontoplan** | BAS-konton per fastighet och kostnadstyp | Konton 1110 (byggnader), 3010 (hyresintäkt), 5010 (fastighetsskötsel), 7720 (fastighetsskatt) | -| **Hyresintäkt-periodisering** | Periodisera hyresintäkter korrekt per månad | Förskottshyra (konto 2970), hyresrabatt, tomgångskostnad | -| **Fastighetsskatt** | Beräkna och bokföra fastighetsskatt/avgift | Taxeringsvärde, skattesats per fastighetstyp, konto 7720, periodisering | -| **Fastighetsavskrivning** | Avskrivningsplan per byggnad (lång löptid) | Komponentavskrivning (K3) eller linjär (K2), konto 1119/7820 | -| **Underhållsfond** | Avsätt medel för planerat underhåll | Avsättning per år, upplösning vid genomfört underhåll, 10-årsplan kopplad | -| **ROT vid renovering** | Hantera ROT-avdrag för hyresgäster vid renovering | Beräkning, personnummer, Skatteverket-rapportering | -| **Indexuppräkning** | Automatisk beräkning av hyreshöjning vid index | KPI-koppling, beräkning per kontrakt, underlag för avisering | - -### Branschrapporter - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Driftnetto per fastighet** | Hyresintäkt minus driftskostnad | Per fastighet/objekt, jämförelse, trend | -| **Vakansgrad** | Andel outhyrda ytor | Per fastighet, trendanalys, intäktsbortfall | -| **Underhållskostnad per m²** | Total underhållskostnad per kvadratmeter | Plan vs utfall, per fastighet, kategori | - -### Smart import - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Hyresreskontra-import** | Importera hyresreskontra | Avier, betalningar, restbelopp; auto-kontosättning | -| **Energirapport-import** | Importera energiförbrukning | El/vatten/fjärrvärme, per fastighet, kostnadsfördelning | - -### Operativa moduler - -| Modul | Beskrivning | Nyckelfunktioner | -|---|---|---| -| **Objektregister** | Fastighets- och lokalöversikt | Adresser, ytor, byggnadsår, dokument | -| **Hyresgästhantering** | Administrera hyresavtal | Avtalstider, kontakt, uppsägningsflöde | -| **Hyresavier** | Generera och skicka avier | Automatisk avisering, tillägg, autogiro | -| **Felanmälan** | Hantera felanmälningar | Webformulär, prioritet, hantverkarstyrning | -| **Underhållsplanering** | Långsiktig och akut | 10-årsplan, kostnadsprognos, status | -| **Besiktning & Rondering** | Dokumentera besiktningar | Protokoll, foto, avvikelserapport | -| **Energiövervakning** | Följ energiförbrukning | El/vatten/värme, jämförelse, energideklaration | diff --git a/supabase/migrations/20240101000021_sru_codes.sql b/supabase/migrations/20240101000021_sru_codes.sql index d366257e..153221bb 100644 --- a/supabase/migrations/20240101000021_sru_codes.sql +++ b/supabase/migrations/20240101000021_sru_codes.sql @@ -260,10 +260,14 @@ begin insert into public.chart_of_accounts (user_id, account_number, account_name, account_class, account_group, account_type, normal_balance, plan_type, is_system_account, sru_code) values (p_user_id, '2440', 'Leverantorsskulder', 2, '24', 'liability', 'credit', 'k1', true, '7230'), - (p_user_id, '2610', 'Utgaende moms 25%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), - (p_user_id, '2611', 'Utgaende moms 12%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), - (p_user_id, '2612', 'Utgaende moms 6%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), + (p_user_id, '2611', 'Utgaende moms forsaljning 25%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), + (p_user_id, '2621', 'Utgaende moms forsaljning 12%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), + (p_user_id, '2631', 'Utgaende moms forsaljning 6%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), + (p_user_id, '2614', 'Utg moms omvand skattskyldighet 25%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), + (p_user_id, '2624', 'Utg moms omvand skattskyldighet 12%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), + (p_user_id, '2634', 'Utg moms omvand skattskyldighet 6%', 2, '26', 'liability', 'credit', 'k1', true, '7231'), (p_user_id, '2641', 'Debiterad ingaende moms', 2, '26', 'liability', 'credit', 'k1', true, '7231'), + (p_user_id, '2645', 'Beraknad ingaende moms forvarv utlandet', 2, '26', 'liability', 'credit', 'k1', true, '7231'), (p_user_id, '2650', 'Redovisningskonto for moms', 2, '26', 'liability', 'credit', 'k1', true, '7231'), (p_user_id, '2710', 'Personalskatt', 2, '27', 'liability', 'credit', 'k1', true, '7231'), (p_user_id, '2731', 'Avrakning socialavgifter', 2, '27', 'liability', 'credit', 'k1', true, '7231'); @@ -282,7 +286,10 @@ begin values (p_user_id, '3001', 'Forsaljning tjanster 25%', 3, '30', 'revenue', 'credit', 'k1', true, '7310'), (p_user_id, '3002', 'Forsaljning varor 25%', 3, '30', 'revenue', 'credit', 'k1', true, '7310'), + (p_user_id, '3003', 'Forsaljning tjanster 6%', 3, '30', 'revenue', 'credit', 'k1', true, '7310'), (p_user_id, '3100', 'Momsfri forsaljning', 3, '31', 'revenue', 'credit', 'k1', true, '7311'), + (p_user_id, '3305', 'Forsaljning tjanst export', 3, '33', 'revenue', 'credit', 'k1', true, '7310'), + (p_user_id, '3308', 'Forsaljning tjanst EU', 3, '33', 'revenue', 'credit', 'k1', true, '7310'), (p_user_id, '3900', 'Ovriga rorelseintakter', 3, '39', 'revenue', 'credit', 'k1', true, '7311'), (p_user_id, '3960', 'Valutakursvinster', 3, '39', 'revenue', 'credit', 'k1', true, '7310'); diff --git a/supabase/migrations/20240101000023_document_version_chain.sql b/supabase/migrations/20240101000023_document_version_chain.sql new file mode 100644 index 00000000..f1496a38 --- /dev/null +++ b/supabase/migrations/20240101000023_document_version_chain.sql @@ -0,0 +1,163 @@ +-- Migration 23: Document Version Chain Hardening +-- Adds cryptographic hash chain + atomic versioning via RPC +-- Resolves: Gap 4 (no hash-chain) + Gap 5 (race condition in versioning) + +-- ============================================================================= +-- 1. New columns on document_attachments +-- ============================================================================= + +ALTER TABLE public.document_attachments + ADD COLUMN IF NOT EXISTS prev_version_hash text, + ADD COLUMN IF NOT EXISTS last_integrity_check_at timestamptz; + +COMMENT ON COLUMN public.document_attachments.prev_version_hash IS + 'SHA-256 hash of the previous version. NULL for version 1 (genesis). Creates tamper-evident chain.'; + +COMMENT ON COLUMN public.document_attachments.last_integrity_check_at IS + 'Timestamp of the last batch integrity verification (set by cron job).'; + +-- Index for cron job: prioritize documents never checked or least recently checked +CREATE INDEX IF NOT EXISTS idx_doc_attachments_integrity_check + ON public.document_attachments (last_integrity_check_at NULLS FIRST) + WHERE is_current_version = true; + +-- ============================================================================= +-- 2. RPC: create_document_version (atomic versioning with row-level lock) +-- Pattern follows next_voucher_number() from migration 016 +-- ============================================================================= + +CREATE OR REPLACE FUNCTION public.create_document_version( + p_user_id uuid, + p_original_doc_id uuid, + p_storage_path text, + p_file_name text, + p_file_size_bytes bigint, + p_mime_type text, + p_sha256_hash text, + p_upload_source text DEFAULT NULL +) +RETURNS uuid +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_current RECORD; + v_root_original_id uuid; + v_new_version integer; + v_new_id uuid; +BEGIN + -- Lock the current version row (prevents concurrent versioning) + SELECT id, version, sha256_hash, original_id, journal_entry_id, + journal_entry_line_id, upload_source + INTO v_current + FROM public.document_attachments + WHERE id = p_original_doc_id + AND user_id = p_user_id + AND is_current_version = true + FOR UPDATE; + + IF NOT FOUND THEN + RAISE EXCEPTION 'Document not found, not owned by user, or not the current version'; + END IF; + + v_root_original_id := COALESCE(v_current.original_id, v_current.id); + v_new_version := v_current.version + 1; + + -- Insert new version with hash chain link + INSERT INTO public.document_attachments ( + user_id, + storage_path, + file_name, + file_size_bytes, + mime_type, + sha256_hash, + version, + original_id, + is_current_version, + uploaded_by, + upload_source, + digitization_date, + journal_entry_id, + journal_entry_line_id, + prev_version_hash + ) VALUES ( + p_user_id, + p_storage_path, + p_file_name, + p_file_size_bytes, + p_mime_type, + p_sha256_hash, + v_new_version, + v_root_original_id, + true, + p_user_id, + COALESCE(p_upload_source, v_current.upload_source), + now(), + v_current.journal_entry_id, + v_current.journal_entry_line_id, + v_current.sha256_hash -- cryptographic link to previous version + ) + RETURNING id INTO v_new_id; + + -- Mark old version as superseded (within same transaction = atomic) + UPDATE public.document_attachments + SET is_current_version = false, + superseded_by_id = v_new_id + WHERE id = v_current.id; + + RETURN v_new_id; +END; +$$; + +GRANT EXECUTE ON FUNCTION public.create_document_version(uuid, uuid, text, text, bigint, text, text, text) TO authenticated; + +-- ============================================================================= +-- 3. RPC: validate_version_chain +-- Verifies that prev_version_hash matches sha256_hash of the preceding version +-- ============================================================================= + +CREATE OR REPLACE FUNCTION public.validate_version_chain( + p_user_id uuid, + p_original_doc_id uuid +) +RETURNS TABLE ( + doc_id uuid, + version integer, + sha256_hash text, + prev_version_hash text, + expected_prev_hash text, + chain_valid boolean +) +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + RETURN QUERY + WITH chain AS ( + SELECT + da.id, + da.version, + da.sha256_hash AS current_hash, + da.prev_version_hash AS stored_prev_hash, + LAG(da.sha256_hash) OVER (ORDER BY da.version) AS computed_prev_hash + FROM public.document_attachments da + WHERE da.user_id = p_user_id + AND (da.id = p_original_doc_id OR da.original_id = p_original_doc_id) + ORDER BY da.version + ) + SELECT + chain.id AS doc_id, + chain.version, + chain.current_hash AS sha256_hash, + chain.stored_prev_hash AS prev_version_hash, + chain.computed_prev_hash AS expected_prev_hash, + CASE + WHEN chain.version = 1 THEN (chain.stored_prev_hash IS NULL) + ELSE (chain.stored_prev_hash IS NOT NULL AND chain.stored_prev_hash = chain.computed_prev_hash) + END AS chain_valid + FROM chain + ORDER BY chain.version; +END; +$$; + +GRANT EXECUTE ON FUNCTION public.validate_version_chain(uuid, uuid) TO authenticated; diff --git a/supabase/migrations/20240101000024_storage_bucket_policies.sql b/supabase/migrations/20240101000024_storage_bucket_policies.sql new file mode 100644 index 00000000..b7192b74 --- /dev/null +++ b/supabase/migrations/20240101000024_storage_bucket_policies.sql @@ -0,0 +1,57 @@ +-- Migration 24: Storage Bucket Policies for WORM Document Archive +-- Resolves: Gap 3 (no immutability on Storage level) +-- +-- Creates a private 'documents' bucket with: +-- - INSERT policy (authenticated users upload to their own folder) +-- - SELECT policy (authenticated users read their own documents) +-- - NO UPDATE policy (prevents overwriting files — WORM) +-- - NO DELETE policy (prevents client-side deletion — WORM) +-- +-- Service role (cron, admin) bypasses RLS and can still access everything. + +-- ============================================================================= +-- 1. Create the 'documents' bucket (private, 50MB file limit) +-- ============================================================================= + +INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types) +VALUES ( + 'documents', + 'documents', + false, + 52428800, -- 50 MB + NULL -- Allow all MIME types (PDFs, images, etc.) +) +ON CONFLICT (id) DO NOTHING; + +-- ============================================================================= +-- 2. INSERT policy: Authenticated users can upload to their own folder +-- ============================================================================= + +CREATE POLICY "documents_insert_own" + ON storage.objects + FOR INSERT + TO authenticated + WITH CHECK ( + bucket_id = 'documents' + AND (storage.foldername(name))[1] = 'documents' + AND (storage.foldername(name))[2] = auth.uid()::text + ); + +-- ============================================================================= +-- 3. SELECT policy: Authenticated users can read their own documents +-- ============================================================================= + +CREATE POLICY "documents_select_own" + ON storage.objects + FOR SELECT + TO authenticated + USING ( + bucket_id = 'documents' + AND (storage.foldername(name))[1] = 'documents' + AND (storage.foldername(name))[2] = auth.uid()::text + ); + +-- ============================================================================= +-- No UPDATE or DELETE policies — WORM compliance +-- Service role bypasses RLS for admin/cron access +-- ============================================================================= diff --git a/supabase/migrations/20240101000025_supplier_invoices.sql b/supabase/migrations/20240101000025_supplier_invoices.sql new file mode 100644 index 00000000..056a8a57 --- /dev/null +++ b/supabase/migrations/20240101000025_supplier_invoices.sql @@ -0,0 +1,342 @@ +-- Migration 25: Leverantorsreskontra (Accounts Payable) +-- Suppliers, supplier invoices, line items, partial payments +-- BFL 5:6-9 verifikationskrav, ML 17:24 inkommande fakturor + +-- ============================================================================= +-- 1. suppliers table +-- ============================================================================= +CREATE TABLE IF NOT EXISTS public.suppliers ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + + -- Basic info + name text NOT NULL, + supplier_type text NOT NULL DEFAULT 'swedish_business' + CHECK (supplier_type IN ('swedish_business', 'eu_business', 'non_eu_business')), + org_number text, + vat_number text, + + -- Contact + email text, + phone text, + + -- Address + address_line1 text, + address_line2 text, + postal_code text, + city text, + country text NOT NULL DEFAULT 'SE', + + -- Payment details + bankgiro text, + plusgiro text, + bank_account text, + iban text, + bic text, + + -- Defaults + default_expense_account text, -- e.g. '5010' + default_payment_terms integer NOT NULL DEFAULT 30, + default_currency text NOT NULL DEFAULT 'SEK', + + -- Notes + notes text, + + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); + +ALTER TABLE public.suppliers ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can view own suppliers" + ON public.suppliers FOR SELECT + USING (auth.uid() = user_id); + +CREATE POLICY "Users can insert own suppliers" + ON public.suppliers FOR INSERT + WITH CHECK (auth.uid() = user_id); + +CREATE POLICY "Users can update own suppliers" + ON public.suppliers FOR UPDATE + USING (auth.uid() = user_id); + +CREATE POLICY "Users can delete own suppliers" + ON public.suppliers FOR DELETE + USING (auth.uid() = user_id); + +CREATE INDEX idx_suppliers_user_id ON public.suppliers (user_id); +CREATE INDEX idx_suppliers_name ON public.suppliers (user_id, name); + +-- ============================================================================= +-- 2. supplier_invoices table +-- ============================================================================= +CREATE TABLE IF NOT EXISTS public.supplier_invoices ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + supplier_id uuid NOT NULL REFERENCES public.suppliers(id) ON DELETE RESTRICT, + + -- Ankomstnummer (BFL running number for incoming invoices) + arrival_number integer NOT NULL, + + -- Supplier's reference + supplier_invoice_number text NOT NULL, + + -- Dates (ML 17:24 requirements) + invoice_date date NOT NULL, + due_date date NOT NULL, + received_date date NOT NULL DEFAULT CURRENT_DATE, + delivery_date date, -- ML krav + + -- Status + status text NOT NULL DEFAULT 'registered' + CHECK (status IN ('registered', 'approved', 'paid', 'partially_paid', 'overdue', 'disputed', 'credited')), + + -- Currency + currency text NOT NULL DEFAULT 'SEK', + exchange_rate numeric, + exchange_rate_date date, + + -- Amounts + subtotal numeric NOT NULL DEFAULT 0, + subtotal_sek numeric, + vat_amount numeric NOT NULL DEFAULT 0, + vat_amount_sek numeric, + total numeric NOT NULL DEFAULT 0, + total_sek numeric, + + -- VAT + vat_treatment text NOT NULL DEFAULT 'standard_25', + reverse_charge boolean NOT NULL DEFAULT false, + + -- Payment + payment_reference text, -- OCR-nummer + paid_at timestamptz, + paid_amount numeric NOT NULL DEFAULT 0, + remaining_amount numeric NOT NULL DEFAULT 0, + + -- Credit note + is_credit_note boolean NOT NULL DEFAULT false, + credited_invoice_id uuid REFERENCES public.supplier_invoices(id) ON DELETE SET NULL, + + -- Bookkeeping links + registration_journal_entry_id uuid REFERENCES public.journal_entries(id) ON DELETE SET NULL, + payment_journal_entry_id uuid REFERENCES public.journal_entries(id) ON DELETE SET NULL, + + -- Transaction link + transaction_id uuid REFERENCES public.transactions(id) ON DELETE SET NULL, + + -- Document (verifikationsunderlag) + document_id uuid REFERENCES public.document_attachments(id) ON DELETE SET NULL, + + -- Notes + notes text, + + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + + -- Constraints + CONSTRAINT uq_supplier_invoices_arrival UNIQUE (user_id, arrival_number), + CONSTRAINT uq_supplier_invoices_ref UNIQUE (user_id, supplier_id, supplier_invoice_number) +); + +ALTER TABLE public.supplier_invoices ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can view own supplier invoices" + ON public.supplier_invoices FOR SELECT + USING (auth.uid() = user_id); + +CREATE POLICY "Users can insert own supplier invoices" + ON public.supplier_invoices FOR INSERT + WITH CHECK (auth.uid() = user_id); + +CREATE POLICY "Users can update own supplier invoices" + ON public.supplier_invoices FOR UPDATE + USING (auth.uid() = user_id); + +CREATE POLICY "Users can delete own supplier invoices" + ON public.supplier_invoices FOR DELETE + USING (auth.uid() = user_id); + +CREATE INDEX idx_supplier_invoices_user_id ON public.supplier_invoices (user_id); +CREATE INDEX idx_supplier_invoices_supplier ON public.supplier_invoices (supplier_id); +CREATE INDEX idx_supplier_invoices_status ON public.supplier_invoices (user_id, status); +CREATE INDEX idx_supplier_invoices_due_date ON public.supplier_invoices (user_id, due_date); + +-- ============================================================================= +-- 3. Per-user arrival number generation (ankomstnummer) +-- ============================================================================= +CREATE OR REPLACE FUNCTION public.get_next_arrival_number(p_user_id uuid) +RETURNS integer AS $$ +DECLARE + next_num integer; +BEGIN + SELECT COALESCE(MAX(arrival_number), 0) + 1 INTO next_num + FROM public.supplier_invoices + WHERE user_id = p_user_id; + RETURN next_num; +END; +$$ LANGUAGE plpgsql; + +-- ============================================================================= +-- 4. supplier_invoice_items table +-- ============================================================================= +CREATE TABLE IF NOT EXISTS public.supplier_invoice_items ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + supplier_invoice_id uuid NOT NULL REFERENCES public.supplier_invoices(id) ON DELETE CASCADE, + + sort_order integer NOT NULL DEFAULT 0, + description text NOT NULL, + quantity numeric NOT NULL DEFAULT 1, + unit text NOT NULL DEFAULT 'st', + unit_price numeric NOT NULL DEFAULT 0, -- exkl. moms (ML krav) + line_total numeric NOT NULL DEFAULT 0, + + -- Bookkeeping + account_number text NOT NULL, -- BAS expense account (4xxx-6xxx) + vat_code text, + vat_rate numeric NOT NULL DEFAULT 0.25, + vat_amount numeric NOT NULL DEFAULT 0, + + created_at timestamptz NOT NULL DEFAULT now() +); + +ALTER TABLE public.supplier_invoice_items ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can view own supplier invoice items" + ON public.supplier_invoice_items FOR SELECT + USING ( + EXISTS ( + SELECT 1 FROM public.supplier_invoices si + WHERE si.id = supplier_invoice_id AND si.user_id = auth.uid() + ) + ); + +CREATE POLICY "Users can insert own supplier invoice items" + ON public.supplier_invoice_items FOR INSERT + WITH CHECK ( + EXISTS ( + SELECT 1 FROM public.supplier_invoices si + WHERE si.id = supplier_invoice_id AND si.user_id = auth.uid() + ) + ); + +CREATE POLICY "Users can update own supplier invoice items" + ON public.supplier_invoice_items FOR UPDATE + USING ( + EXISTS ( + SELECT 1 FROM public.supplier_invoices si + WHERE si.id = supplier_invoice_id AND si.user_id = auth.uid() + ) + ); + +CREATE POLICY "Users can delete own supplier invoice items" + ON public.supplier_invoice_items FOR DELETE + USING ( + EXISTS ( + SELECT 1 FROM public.supplier_invoices si + WHERE si.id = supplier_invoice_id AND si.user_id = auth.uid() + ) + ); + +CREATE INDEX idx_supplier_invoice_items_invoice ON public.supplier_invoice_items (supplier_invoice_id); + +-- ============================================================================= +-- 5. supplier_invoice_payments table (partial payments) +-- ============================================================================= +CREATE TABLE IF NOT EXISTS public.supplier_invoice_payments ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + supplier_invoice_id uuid NOT NULL REFERENCES public.supplier_invoices(id) ON DELETE CASCADE, + + payment_date date NOT NULL, + amount numeric NOT NULL, + currency text NOT NULL DEFAULT 'SEK', + exchange_rate numeric, + exchange_rate_difference numeric DEFAULT 0, -- kursdifferens + + journal_entry_id uuid REFERENCES public.journal_entries(id) ON DELETE SET NULL, + transaction_id uuid REFERENCES public.transactions(id) ON DELETE SET NULL, + notes text, + + created_at timestamptz NOT NULL DEFAULT now() +); + +ALTER TABLE public.supplier_invoice_payments ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can view own supplier invoice payments" + ON public.supplier_invoice_payments FOR SELECT + USING ( + EXISTS ( + SELECT 1 FROM public.supplier_invoices si + WHERE si.id = supplier_invoice_id AND si.user_id = auth.uid() + ) + ); + +CREATE POLICY "Users can insert own supplier invoice payments" + ON public.supplier_invoice_payments FOR INSERT + WITH CHECK ( + EXISTS ( + SELECT 1 FROM public.supplier_invoices si + WHERE si.id = supplier_invoice_id AND si.user_id = auth.uid() + ) + ); + +CREATE INDEX idx_supplier_invoice_payments_invoice ON public.supplier_invoice_payments (supplier_invoice_id); + +-- ============================================================================= +-- 6. Add supplier_invoice_id to transactions +-- ============================================================================= +ALTER TABLE public.transactions + ADD COLUMN IF NOT EXISTS supplier_invoice_id uuid REFERENCES public.supplier_invoices(id) ON DELETE SET NULL; + +CREATE INDEX IF NOT EXISTS idx_transactions_supplier_invoice ON public.transactions (supplier_invoice_id); + +-- ============================================================================= +-- 7. Expand journal_entries source_type constraint +-- ============================================================================= +ALTER TABLE public.journal_entries + DROP CONSTRAINT IF EXISTS journal_entries_source_type_check; + +ALTER TABLE public.journal_entries + ADD CONSTRAINT journal_entries_source_type_check + CHECK (source_type IN ( + 'manual', 'bank_transaction', 'invoice_created', + 'invoice_paid', 'invoice_cash_payment', 'credit_note', 'salary_payment', + 'opening_balance', 'year_end', + 'storno', 'correction', 'import', 'system', + 'supplier_invoice_registered', 'supplier_invoice_paid', + 'supplier_invoice_cash_payment', 'supplier_credit_note' + )); + +-- ============================================================================= +-- 8. Audit triggers for new tables +-- ============================================================================= +CREATE TRIGGER audit_suppliers + AFTER INSERT OR UPDATE OR DELETE ON public.suppliers + FOR EACH ROW EXECUTE FUNCTION public.write_audit_log(); + +CREATE TRIGGER audit_supplier_invoices + AFTER INSERT OR UPDATE OR DELETE ON public.supplier_invoices + FOR EACH ROW EXECUTE FUNCTION public.write_audit_log(); + +CREATE TRIGGER audit_supplier_invoice_items + AFTER INSERT OR UPDATE OR DELETE ON public.supplier_invoice_items + FOR EACH ROW EXECUTE FUNCTION public.write_audit_log(); + +-- ============================================================================= +-- 9. Updated_at triggers +-- ============================================================================= +CREATE OR REPLACE FUNCTION public.update_updated_at_column() +RETURNS trigger AS $$ +BEGIN + NEW.updated_at = now(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER set_updated_at_suppliers + BEFORE UPDATE ON public.suppliers + FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column(); + +CREATE TRIGGER set_updated_at_supplier_invoices + BEFORE UPDATE ON public.supplier_invoices + FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column(); diff --git a/supabase/migrations/20240101000026_drop_restaurant_module.sql b/supabase/migrations/20240101000026_drop_restaurant_module.sql new file mode 100644 index 00000000..308c6428 --- /dev/null +++ b/supabase/migrations/20240101000026_drop_restaurant_module.sql @@ -0,0 +1,20 @@ +-- Drop 14 restaurant module tables — zero code references, zero rows. +-- These are industry-specific tables that don't belong in base ERP. + +-- Children first +DROP TABLE IF EXISTS public.recipe_ingredients CASCADE; +DROP TABLE IF EXISTS public.supplier_order_items CASCADE; +DROP TABLE IF EXISTS public.menu_items CASCADE; +DROP TABLE IF EXISTS public.menu_categories CASCADE; +DROP TABLE IF EXISTS public.reservations CASCADE; +DROP TABLE IF EXISTS public.shifts CASCADE; + +-- Parents / standalone +DROP TABLE IF EXISTS public.menus CASCADE; +DROP TABLE IF EXISTS public.recipes CASCADE; +DROP TABLE IF EXISTS public.ingredients CASCADE; +DROP TABLE IF EXISTS public.staff_members CASCADE; +DROP TABLE IF EXISTS public.supplier_orders CASCADE; +DROP TABLE IF EXISTS public.restaurant_tables CASCADE; +DROP TABLE IF EXISTS public.waste_entries CASCADE; +DROP TABLE IF EXISTS public.restaurant_capacity CASCADE; diff --git a/supabase/migrations/20240101000027_drop_unused_module_tables.sql b/supabase/migrations/20240101000027_drop_unused_module_tables.sql new file mode 100644 index 00000000..420f298c --- /dev/null +++ b/supabase/migrations/20240101000027_drop_unused_module_tables.sql @@ -0,0 +1,58 @@ +-- Drop 36 unused tables — zero .from() calls, zero rows. +-- Grouped by module; children before parents. + +-- HR / Payroll +DROP TABLE IF EXISTS public.salary_additions CASCADE; +DROP TABLE IF EXISTS public.salary_run_items CASCADE; +DROP TABLE IF EXISTS public.salary_payments CASCADE; +DROP TABLE IF EXISTS public.salary_runs CASCADE; +DROP TABLE IF EXISTS public.absence_records CASCADE; +DROP TABLE IF EXISTS public.mileage_entries CASCADE; +DROP TABLE IF EXISTS public.employees CASCADE; + +-- Asset Management +DROP TABLE IF EXISTS public.depreciation_schedule CASCADE; +DROP TABLE IF EXISTS public.assets CASCADE; +DROP TABLE IF EXISTS public.asset_categories CASCADE; + +-- Bank Reconciliation +DROP TABLE IF EXISTS public.bank_reconciliation_items CASCADE; +DROP TABLE IF EXISTS public.bank_reconciliation_sessions CASCADE; +DROP TABLE IF EXISTS public.account_balances CASCADE; + +-- Budgeting / Forecasting +DROP TABLE IF EXISTS public.budget_entries CASCADE; +DROP TABLE IF EXISTS public.budgets CASCADE; +DROP TABLE IF EXISTS public.cash_flow_forecasts CASCADE; + +-- Orders / Quotes +DROP TABLE IF EXISTS public.order_items CASCADE; +DROP TABLE IF EXISTS public.orders CASCADE; +DROP TABLE IF EXISTS public.quote_items CASCADE; +DROP TABLE IF EXISTS public.quotes CASCADE; + +-- Analytics / KPI +DROP TABLE IF EXISTS public.ai_insights_cache CASCADE; +DROP TABLE IF EXISTS public.financial_insights CASCADE; +DROP TABLE IF EXISTS public.kpi_snapshots CASCADE; + +-- Tax / Compliance +DROP TABLE IF EXISTS public.agi_declarations CASCADE; +DROP TABLE IF EXISTS public.annual_reports CASCADE; +DROP TABLE IF EXISTS public.tax_rates CASCADE; +DROP TABLE IF EXISTS public.year_end_closings CASCADE; + +-- Supplier Payments +DROP TABLE IF EXISTS public.supplier_payment_items CASCADE; +DROP TABLE IF EXISTS public.supplier_payments CASCADE; + +-- Module System +DROP TABLE IF EXISTS public.module_configs CASCADE; +DROP TABLE IF EXISTS public.module_imports CASCADE; +DROP TABLE IF EXISTS public.module_kpi_targets CASCADE; + +-- Other +DROP TABLE IF EXISTS public.onboarding_checklist CASCADE; +DROP TABLE IF EXISTS public.payment_methods CASCADE; +DROP TABLE IF EXISTS public.recurring_invoices CASCADE; +DROP TABLE IF EXISTS public.supplier_invoice_attestations CASCADE; diff --git a/tests/helpers.ts b/tests/helpers.ts index 510aba58..2abd30e0 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -136,6 +136,7 @@ export function makeTransaction(overrides: Partial = {}): Transacti category: 'uncategorized', is_business: null, invoice_id: null, + supplier_invoice_id: null, potential_invoice_id: null, journal_entry_id: null, mcc_code: null, @@ -235,6 +236,8 @@ export function makeDocumentAttachment( digitization_date: '2024-06-15T14:30:00Z', journal_entry_id: null, journal_entry_line_id: null, + prev_version_hash: null, + last_integrity_check_at: null, created_at: '2024-06-15T14:30:00Z', updated_at: '2024-06-15T14:30:00Z', ...overrides, diff --git a/types/index.ts b/types/index.ts index 401013cf..1175f023 100644 --- a/types/index.ts +++ b/types/index.ts @@ -30,6 +30,12 @@ export type CustomerType = // Invoice status export type InvoiceStatus = 'draft' | 'sent' | 'paid' | 'overdue' | 'cancelled' | 'credited' +// Supplier types +export type SupplierType = 'swedish_business' | 'eu_business' | 'non_eu_business' + +// Supplier invoice status +export type SupplierInvoiceStatus = 'registered' | 'approved' | 'paid' | 'partially_paid' | 'overdue' | 'disputed' | 'credited' + // VAT treatment export type VatTreatment = | 'standard_25' // 25% Swedish VAT @@ -39,6 +45,9 @@ export type VatTreatment = | 'export' // Non-EU export (0%) | 'exempt' // VAT exempt +// Accounting method (bokföringsmetod) +export type AccountingMethod = 'accrual' | 'cash' + // Moms reporting period export type MomsPeriod = 'monthly' | 'quarterly' | 'yearly' @@ -97,6 +106,14 @@ export interface CompanySettings { iban: string | null bic: string | null + // Accounting method + accounting_method: AccountingMethod + + // Invoice settings + invoice_prefix: string | null + next_invoice_number: number + invoice_default_days: number + // Onboarding onboarding_step: number onboarding_complete: boolean @@ -112,20 +129,20 @@ export interface BankConnection { user_id: string bank_name: string - bank_id: string + provider: string // Enable Banking specific session_id: string | null authorization_id: string | null // Account info - accounts: BankAccount[] + accounts_data: BankAccount[] // Status status: BankConnectionStatus // Consent - consent_expires_at: string | null + consent_expires: string | null last_synced_at: string | null created_at: string @@ -167,6 +184,9 @@ export interface Transaction { // Linked invoice (for matching) invoice_id: string | null + // Linked supplier invoice (for matching) + supplier_invoice_id: string | null + // Potential invoice match (suggested, not confirmed) potential_invoice_id: string | null @@ -221,6 +241,135 @@ export interface Customer { updated_at: string } +// Supplier +export interface Supplier { + id: string + user_id: string + + name: string + supplier_type: SupplierType + + email: string | null + phone: string | null + + address_line1: string | null + address_line2: string | null + postal_code: string | null + city: string | null + country: string + + org_number: string | null + vat_number: string | null + + bankgiro: string | null + plusgiro: string | null + bank_account: string | null + iban: string | null + bic: string | null + + default_expense_account: string | null + default_payment_terms: number + default_currency: string + + notes: string | null + + created_at: string + updated_at: string +} + +// Supplier Invoice +export interface SupplierInvoice { + id: string + user_id: string + supplier_id: string + + arrival_number: number + supplier_invoice_number: string + + invoice_date: string + due_date: string + received_date: string + delivery_date: string | null + + status: SupplierInvoiceStatus + + currency: string + exchange_rate: number | null + exchange_rate_date: string | null + + subtotal: number + subtotal_sek: number | null + vat_amount: number + vat_amount_sek: number | null + total: number + total_sek: number | null + + vat_treatment: VatTreatment + reverse_charge: boolean + + payment_reference: string | null + paid_at: string | null + paid_amount: number + remaining_amount: number + + is_credit_note: boolean + credited_invoice_id: string | null + + registration_journal_entry_id: string | null + payment_journal_entry_id: string | null + + transaction_id: string | null + document_id: string | null + + notes: string | null + + created_at: string + updated_at: string + + // Relations (populated when fetched) + supplier?: Supplier + items?: SupplierInvoiceItem[] + payments?: SupplierInvoicePayment[] +} + +// Supplier Invoice Item +export interface SupplierInvoiceItem { + id: string + supplier_invoice_id: string + + sort_order: number + description: string + quantity: number + unit: string + unit_price: number + line_total: number + + account_number: string + vat_code: string | null + vat_rate: number + vat_amount: number + + created_at: string +} + +// Supplier Invoice Payment (partial payments) +export interface SupplierInvoicePayment { + id: string + supplier_invoice_id: string + + payment_date: string + amount: number + currency: string + exchange_rate: number | null + exchange_rate_difference: number + + journal_entry_id: string | null + transaction_id: string | null + notes: string | null + + created_at: string +} + // Invoice export interface Invoice { id: string @@ -372,6 +521,54 @@ export interface CreateCustomerInput { notes?: string } +export interface CreateSupplierInput { + name: string + supplier_type: SupplierType + email?: string + phone?: string + address_line1?: string + address_line2?: string + postal_code?: string + city?: string + country?: string + org_number?: string + vat_number?: string + bankgiro?: string + plusgiro?: string + bank_account?: string + iban?: string + bic?: string + default_expense_account?: string + default_payment_terms?: number + default_currency?: string + notes?: string +} + +export interface CreateSupplierInvoiceInput { + supplier_id: string + supplier_invoice_number: string + invoice_date: string + due_date: string + delivery_date?: string + currency?: string + exchange_rate?: number + vat_treatment?: VatTreatment + reverse_charge?: boolean + payment_reference?: string + notes?: string + items: CreateSupplierInvoiceItemInput[] +} + +export interface CreateSupplierInvoiceItemInput { + description: string + quantity: number + unit?: string + unit_price: number + account_number: string + vat_code?: string + vat_rate?: number +} + export interface CreateInvoiceInput { customer_id: string invoice_date: string @@ -497,6 +694,7 @@ export type JournalEntrySourceType = | 'bank_transaction' | 'invoice_created' | 'invoice_paid' + | 'invoice_cash_payment' | 'credit_note' | 'salary_payment' | 'opening_balance' @@ -505,6 +703,10 @@ export type JournalEntrySourceType = | 'correction' | 'import' | 'system' + | 'supplier_invoice_registered' + | 'supplier_invoice_paid' + | 'supplier_invoice_cash_payment' + | 'supplier_credit_note' // Journal entry status export type JournalEntryStatus = 'draft' | 'posted' | 'reversed' @@ -1203,6 +1405,8 @@ export interface DocumentAttachment { digitization_date: string | null journal_entry_id: string | null journal_entry_line_id: string | null + prev_version_hash: string | null + last_integrity_check_at: string | null created_at: string updated_at: string } @@ -1234,6 +1438,7 @@ export type AuditAction = | 'DOCUMENT_DELETE_BLOCKED' | 'RETENTION_BLOCK' | 'SECURITY_EVENT' + | 'INTEGRITY_FAILURE' export interface AuditLogEntry { id: string diff --git a/vercel.json b/vercel.json index 5267f667..65fea6ef 100644 --- a/vercel.json +++ b/vercel.json @@ -1,9 +1,5 @@ { "crons": [ - { - "path": "/api/tiktok/cron", - "schedule": "0 7 * * *" - }, { "path": "/api/deadlines/status/cron", "schedule": "0 6 * * *" @@ -23,6 +19,10 @@ { "path": "/api/banking/sync/cron", "schedule": "0 5 * * *" + }, + { + "path": "/api/documents/verify/cron", + "schedule": "0 3 * * 0" } ] }