InvoiceInvoker: inwokacja

Dziś początek konkursu Daj się poznać – pracę czas zacząć!

IT, dziedzino moja, ty jesteś jak…
…no dobra, bez przesady. Jak zapowiedziałem, startuję z programem służącym do wystawiania i przechowywania faktur (VAT). Projekt zyskał już nazwę: InvoiceInvoker (w kategorii o tej samej nazwie będę umieszczał wpisy konkursowe) i konto na CodePlex (na razie nieupublicznione). Kolejnym etapem będzie sformułowanie kilku podstawowych założeń projektowych.

Dane
Na początek założenia raczej bardziej ogólne, niż ściśle programistyczne: faktury powinny być zgodne z obowiązującymi przepisami, produkty – mieć przypisaną odpowiednią stawkę VAT i klasyfikację PKWiU (tym na szczęście zajmie się użytkownik), a numery NIP i REGON – być sprawdzane pod względem poprawności. Czeka mnie więc trochę lektury i kontaktu ze światem przepisów gospodarczych. Kluczowe informacje postaram się zamieszczać na blogu, aby pokazać, że programowanie to nie tylko kodowanie, ale i poszerzanie ogólnej wiedzy.
Czas na garść założeń czysto programistycznych. Użytkownik powinien mieć możliwość zdefiniowania stałych klientów i produktów, a także szablonów faktur – tak, aby wystawienie faktury za stałe comiesięczne zamówienie wymagało trzech kliknięć LPM. Powinien też móc wybrać format numeru faktury (np. 1/8/10 lub 01-08-2010).
Do przechowywania danych użyję Microsoft SQL Server Compact 3.5. Dobierać się do nich będę za pomocą LINQ to SQL.

Funkcjonalności
Na razie do głowy przychodzi mi tylko jedna funkcjonalność programu, o której warto wspomnieć, a która nie pasuje do kategorii Dane. Jest to przemiana mrocznych wnętrzności bazy danych w miły oku (przynajmniej oku wystawiającego; klienta – niekoniecznie) dokument PDF. Google w 0.18 s znajduje na to miliony sposobów, w tym 7, z których na pewno coś wybiorę.

Technologie
Jako że organizator konkursu zachęca do użycia w projekcie konkursowym technologii, z którymi uczestnik nie miał dotąd styczności, zdecydowałem się na skorzystanie z ASP.NET MVC. Dotychczas tworzyłem tylko programy desktopowe i od jakiegoś czasu chciałem to zmienić – teraz mam świetną okazję.
W przeprowadzaniu testów jednostkowych pomoże mi natomiast framework NUnit.
Niewymagający komentarza miszmasz pozostałych wybranych technologii / aplikacji / komponentów: Visual Studio 2010, LINQ to SQL, CodePlex, Windows 7, .NET 4.0, Mercurial, SQL Server Compact 3.5.

To by było na tyle w kwestii podstawowych założeń projektu, kolejne będą się rodzić w miarę postępu prac nad nim.

…Witryna na wciąż otwarta przechodniom ogłasza,
Że gościnna i wszystkich w gościnę zaprasza.

Zapraszam serdecznie do śledzenia mojego udziału w konkursie. Wszelkie sugestie – dotyczące tematyki wpisów bądź samego bloga – mile widziane!

Zmiana planów

Minął zaledwie tydzień odkąd zacząłem swoje zmagania z projektem DigitalWallet, a już postanowiłem zawiesić prace nad nim. Nie nie jest to jednak konsekwencją mojego lenistwa, a faktu zorganizowania przez Maćka konkursu Daj się poznać!, w którym, nie bez pewnych oporów, zdecydowałem się wystartować. Opory wynikają oczywiście ze zbieżności niektórych danych – jak nazwisko, imię ojca, adres zameldowania itd. – moich i organizatora. Dlatego na czas trwania konkursu Maciek przestaje być moim bratem i organem podsuwającym pomysły i rozwiązania. Co więcej, każdy remis (o jakim mowa w punkcie 10.b. regulaminu) przegrywam, a także, gdybym za sprawą uśmiechu losu uzyskał najwięcej głosów w fazie wyłaniania zwycięzcy, zrzekam się pierwszeństwa wyboru nagrody na rzecz osoby (lub osób remisujących) z miejsca drugiego. Mam nadzieję, że takie warunki (skonsultowane z organizatorem i przez niego zaakceptowane) rozwieją ewentualne podejrzenia o „ustawienie” konkursu, tak jak rozwiały moje wątpliwości co do etyczności i stosowności mojego w nim udziału.
Abstrahując od kwestii pokrewieństwa: konkurs tej formuły jest zbyt rzadką i zbyt kuszącą okazją, by z niej nie skorzystać. Stanowić będzie to, czego najbardziej brakuje uczącemu się programiście: źródło motywacji, a także sposób i szansę na zaistnienie w dev-społeczności. Wystartuję w nim z projektem innym niż ten rozpoczęty tydzień temu (powodem znowuż jest zbytnie powiązanie z Maciejem), choć pozostanę w tematyce „ekonomicznej” – mój projekt konkursowy to program służący do wystawiania i przechowywania faktur, którego wyimaginowanym odbiorcą jest przedsiębiorca szukający nieskomplikowanej (tzn. służącej jedynie za elektrniczną bazę faktur, nieoferującej wyliczania podatków i wypełniania PIT-ów) aplikacji tego typu.
Mój pośpiech w podejmowaniu decyzji o udziale w konkursie i wyborze projektu wynika stąd, że za kilkanaście godzin wyruszam na wakacje. Wracam w pierwszych dniach sierpnia i zamierzam od razu zabrać się do pracy – nie tracić cennych dni na rozterki i szukanie pomysłu na projekt konkursowy.

Czaję bazę?

Punkt drugi listy wypunktowanej w poprzednim wpisie głosi: projektowanie bazy danych. Jest to dość kłopotliwy problem, który można rozwiązać na wiele sposobów. Kłopotliwość polega na wybraniu rozwiązania najlepiej dostosowanego do wymagań projektowych. Wiadomo, że każdy błąd popełniony podczas projektowania mści się tym bardziej, im później zostanie wykryty i im więcej warstw aplikacji opiera się na błędnym module. Na bazie, jak to na bazie, opiera się właściwie wszystko – dlatego błędy na tym etapie są szczególnie niemile widziane.

Do dzieła. Przypomnę wymagania dotyczące tego etapu: „chcę nadawać wydatkom kategorie”, „chcę móc zdefiniować wydatki stałe”. Dosyć oczywiste wydają się więc tabele bazy danych: kategorie wydatków, wydatki jednorazowe, wydatki stałe – i ich przyjemniejsze odpowiedniki: kategorie przychodów, przychody jednorazowe, przychody stałe.

Kategorie nie powinny sprawić problemu – niech zawierają, oprócz identyfikatora, tylko nazwę.

Wydatki (przychody) jednorazowe niech cechuje ich wartość, kategoria, nazwa (warto odróżnić kategorię od nazwy: w kategorii „alkohol” może znajdować się np. wydatek o nazwie „komandos z braciszkiem”), data, flaga oczekujący / zapłacony (otrzymany) i notatki (np. n-ta z kolei notatka: „zapamiętać: nigdy więcej komandosa”).

Wydatki (przychody) stałe wymagają, jak wspomniałem dwie notki niżej, zastanowienia. Pierwsza moja myśl: mogłyby mieć przypisany okres czasu (np. czynsz za akademik: październik 2009 – czerwiec 2010). Przy rozliczaniu jakiegoś okresu (np. pierwszy kwartał 2010) wyliczałbym mnożnik danego wydatku (w danym przykładzie: 3, bo rozliczam 3 miesiące) i obliczał kwotę, o którą wydatek ten uszczuplił portfel użytkownika. Nieco niewygodne, ale oszczędne – każdy wydatek to tylko jeden wiersz w tabeli bazy. Wtem! Druga moja myśl: akcja „weryfikuj wydatki stałe”, o której mowa w wymaganiach, wymaga, aby dany wydatek stały każdego miesiąca osobno mógł być oznaczony jako zapłacony. Okresowość wydatków może być realizowana przez dodanie ich tylu, ilu miesięcy dotyczą (po jednym wydatku na miesiąc). Decyduję się więc na rozwiązanie najprostsze: wydatki (przychody) stałe mają identyczną strukturę z jednorazowymi. W polu „data” dni nie mają znaczenia – wydatek (przychód) dotyczy całego miesiąca.

Podsumowując, baza danych zawiera sześć tabel:
– ExpenseCategories / IncomeCategories o polach:
1) Id [int]
2) Name [nvarchar]

– Expenses / ConstantExpenses / Incomes / ConstantIncomes o jednolitej strukturze pól:
1) Id [int]
2) ExpenseCategoryId / IncomeCategoryId [int]
3) Name [nvarchar]
4) Value [money]
5) Date [datetime]
6) Paid / Gained [bit]
7) Notes [nvarchar]

Solution: making of

Skoro etap formułowania, studiowania i interpretowania wymagań mam już za sobą, czas przejść do etapu kolejnego: projektowania aplikacji. Niechże składa się ono z takich oto kroków:
1. projektowanie solucji,
2. projektowanie bazy danych,
3. projektowanie warstwy logiki biznesowej,
4. projektowanie warstwy interfejsu użytkownika.

Zaprojektować by się można na amen, dlatego pomiędzy powyższymi punktami odbywać się będzie kodowanie zaprojektowanych modułów.

Ale do rzeczy. Punkt pierwszy rzecze: projektowanie solucji. W tym kroku pomocne będzie zerknięcie na pozostałe punkty – widać, że logika jest wyraźnie oddzielona od interfejsu użytkownika. Aby podkreślić ten podział, elementy te zostaną umieszczone w osobnych projektach: DigitalWallet.Logic i DigitalWallet.UI. Nie wspomniałem jeszcze o testach jednostkowych logiki biznesowej – one też zasługują na osobny projekt. Do już wspomnianej dwójki dodaję więc DigitalWallet.Logic.Tests. Utworzone mam zatem trzy projekty w jednej solucji, to bring them all and in Solution Explorer bind them

DigitalWallet: interpretacja wymagań

Opis projektu, otrzymany od Maćka, wygląda tak:

„Chodzi mi o aplikację, która będzie monitorować moje wydatki i przychody. Sprawdzałem kilka rozwiązań online, ale są.. zbyt skomplikowane. Chcę po prostu uruchomić program, dodać pozycję i zamknąć program. W razie potrzeby otworzyć go znowu, wejść na ekran z podsumowaniem danego miesiąca i zobaczyć czy jestem na plusie czy minusie. Od roku robię to w excelu, jednak nie jest to najwygodniejsze. Podstawowe wymagania:
1) aplikacja desktop, najchętniej w WPF
2) wszystkie operacje chcę zrobić bez dotykania myszki – czyli skróty klawiszowe
3) aplikacja może chować się do tray i przy ponownym odpaleniu exeka sprawdzać czy jest już uruchomiona instancja – jeżeli tak, to pokazać tą, która jest aktualnie w trayu… ale to przyjemny bajer który nie jest mi konieczny, wystarczy na początek, że będzie jakieś zabezpieczenie przed uruchomieniem więcej niż 1 instancji aplikacji naraz
4) nie chcę instalować żadnego serwera baz danych, więc zostaje sqlite, slq server compact lub xml (chociaż xmla wolałbym uniknąć)
5) chcę nadawać wydatkom kategorie, tak aby w prosty sposób zobaczyć ile w danym miesiącu wydałem na benzynę, ile na alkohol a ile na rachunki
6) chcę móc zdefiniować wydatki „stałe” i zweryfikować wybrany miesiąc pod ich kątem… tzn. wiem, że co miesiąc muszę wydać X na mieszkanie, Y na ZUS, a Z na rachunek za komórkę i po wybraniu jakiejś akcji (np. „weryfikuj wydatki stałe”) chcę dostać info jeśli w którymś miesiącu zapomniałem uzupełnić którejś z tych pozycji”

Jak widać, chodzi o jak najprostszą i jak najwygodniejszą w obsłudze aplikację do monitorowania wydatków. Co do wypunktowanych wymogów:

ad. 1)  Jako że projekt domyślnie ma być tworzony w .NET, uważam się za zwolnionego z dywagacji na temat wyboru systemu operacyjnego i środowiska programistycznego: korzystał będę Windows 7 i Visual Studio 2010. WPF na szczęście nie stanowi problemu, może jedynie taki, że daje spore możliwości na stworzenie miłego oku interfejsu użytkownika – a ja te możliwości będę starał się wykorzystać,  co grozi powstaniem UI wypranego ze stylu i smaku.
ad. 2) Tutaj problem stanowić będzie zapewnienie wygody użytkowania. Postaram się unikać znanych z Visual Studio kalamburów typu ctrl+shift+F11, a stosować skróty intuicyjne. Nie wiem jeszcze, jakiż to intuicyjny skrót wywoła akcję „weryfikuj wydatki stałe”, jednak o tym myślał będę w późniejszej fazie projektu.
ad. 3) Obiło mi się o oczy takie coś jak NotifyIcon – dokładniej zajmę się tym, kiedy skończę warstwę logiki biznesowej i przejdę do projektowania interfejsu użytkownika.
ad. 4) Sqlite nie gości na moim dysku, xmla, zgodnie z sugestią, unikam. Microsoft SQL Server Compact 3.5 – wybieram cię!
ad. 5) Mówisz – masz: projektując bazę danych, będę pamiętał o polu Category przypisanym do wydatków i przychodów.
ad. 6)  Przewiduję kwestie do rozstrzygnięcia: czy wydatek stały będzie uwzględniany zawsze, każdego miesiąca, czy będzie miał przypisany okres czasu, którego dotyczy? A może będzie traktowany tak samo jak wydatek jednorazowy, tylko dodawany będzie na początku każdego miesiąca?

Można zauważyć, że Maciek nie wymaga wyboru konkretnych technologii – jedynym wymogiem w tej kwestii jest zwolnienie go z potrzeby instalowania dodatkowych pakietów (pkt. 4). Wygoda przede wszystkim: skróty klawiszowe, nieskomplikowaność aplikacji (tzn. aplikacja ma być mniej skomplikowana niż słowo „nieskomplikowaność”); a przy tym tylko dwa wymogi co do funkcjonalności programu (pkt. 5 i 6). To daje mi sporą swobodę i pole do popisu przy projektowaniu, jednak zarazem napawa przeczuciem, że w trakcie pracy nad projektem niejednokrotnie pojawią się kolejne sugestie co do funkcjonalności, co z kolei zmusi mnie do przeprojektowania UI – niezbędnego, by utrzymać wygodę użytkowania. Cóż, klient na szpan.

Hello world!

Witam, oto kolejny z wielu blogów o tematyce programistycznej. Powstał głównie na potrzeby mojego wakacyjnego projektu, DigitalWallet – aplikacji służącej do monitorowania domowego budżetu. O czym będzie traktował po zakończeniu pracy nad projektem? Na razie nie mam planów.

Kilka słów o mnie…

Nazywam się Michał Aniserowicz, miesiąc temu skończyłem pierwszy rok inforamtyki na wydziale Elektroniki i Technik Informacyjnych Politechniki Warszawskiej. Od kilku lat programuję uczę się programować, głównie w .NET. Co roku zabieram się za kolejne wakacyjne projekty, z różnym skutkiem – niekiedy kodowanie kończyło się stwierdzeniem: ok, już to umiem, nie ma potrzeby kończyć. Tym razem, aby tak się nie stało, postanowiłem upublicznić swoją pracę, co ma mnie zmotywować do pełnego jej ukończenia. Inny powód założenia bloga to korzyści z opisywania własnych rozwiązań i użytych technologii: wtedy nauka jest efektywniejsza, być może podczas opisywania swoich zmagań wpadnę na lepsze rozwiązania napotkanych problemów. Kolejnym powodem jest to, że blogowanie było sugestią [zlecenio/pomysło]dawacy projektu, Maćka Aniserowicza, który jest jednocześnie, nie da się ukryć, moim bratem.

…i kilka o projekcie

DigitalWallet to projekt, którego wynikiem ma być prosta aplikacja monitorująca wydatki i przychody. Jego celem, oczywiście oprócz powstania samego programu, jest wzbogacenie wiedzy, poznanie obcych mi dotąd praktyk programistycznych.

Główne wymagania [zlecenio/pomysło]dawcy:
1) aplikacja desktop, najlepiej w WPF,
2) wszystkie operacje możliwe do wykonania bez użycia myszki (skróty klawiszowe),
3) aplikacja może chować się do tray i przy ponownym uruchomieniu exeka sprawdzać, czy jest już uruchomiona instancja – jeżeli tak, to pokazać tą, która jest aktualnie w trayu,
4) aplikacja ma korzystać z slq server compact lub sqlite.