ogólny zarys aplikacji + struktura klas i bazy danych

0

Witam!
Uczę się C# i dlatego mam zamiar stworzyć aplikacje (która ma być używana w firmie narzeczonej), ale służy mi głównie do nauki .

Aplikacja ma służyć do zarządzania zamówieniami, a ściśle mówiąc do ich monitorowania i obliczania obrotu firmy.
Każde zamówienie może zawierać kilka zadań i chciałbym w nich móc zdefiniować m.in.:

  • klienta który złożył zamówienie,
  • datę złożenia zamówienia,
  • datę realizacji całego zamówienia,
  • wykonawce/zleceniobiorce zadania w zamówieniu,
  • datę zlecenia wykonania zadania,
  • datę realizacji zadania

Np.
Zamówienie 1: Klient: xx; data zamówienia: 18.05.2010
Zadania:
1 wizytówki 200szt, wykonawca: jakaś firma itd.
2 projekt wizytówek, wykonawca: (imię jednego z pracowników)

Wątpliwości:

  1. Mogę zapisywać pracowników w tabeli "kontrahent" a w tab. "Typ" stworzyć typ o nazwie "pracownik" czy mam tworzyć nową tabele z pracownikami?
  2. podczas zapisu kontrahenta będę mu nadawać właściwości:
    • "osoba fizyczna" lub "firma" wówczas wypełniam odpowiednio rekordy "nazwa firmy", "imię", "nazwisko", "NIP", "Regon" lub wpisuje do nich wartość "NULL"
    • "klient" lub "zleceniobiorca" albo "klient" i "zleceniobiorca"

Klasy:

  1. Kontrahent
  2. Adres
  3. Typ <enum>
  4. Grupa <enum>
  5. Email
  6. Tel
  7. Zamowienia
  8. Szczegoly zamowien

Struktura bazy danych:

Zamowienia
id|id_klient|data zamowienia|data realizacji|uwagi

Detale zamowien
id|nazwa|ilosc|zleceniobiorca|data zlecenia|data realizacji zlecenia|cena kupno|cena sprzedaz|VAT|uwagi|id zamowienia

Kontrahent
Id | krotka nazwa | nazwa | imię | nazwisko | NIP | Regon | nazwa banku | nr konta bankowego | grupa

adres
id | kod pocztowy | miasto | ulica | nr domu/mieszkania

Grupa
Id | Nazwa
1 | osoba fizyczna
2 | firma

typ
id | nazwa
1 | klient
2 | zleceniobiorca

email
id|mail

tel
id|tel

kontrahent/email
id kontrahenta | id emli

kontrahent/tel
id kontrahenta | id tel

kontrahent/adres
id kontrahenta | id adres

kontrahent/typ
id kontrahenta | id typ

0
  1. Mogę zapisywać pracowników w tabeli "kontrahent" a w tab. "Typ" stworzyć typ o nazwie "pracownik" czy mam tworzyć nową tabele z pracownikami?

Właściwie można by uznać że dana osoba (podmiot) raz może być kontrahentem, a raz wykonawcą (pracownikiem). Ale charakter w jakim występuje podmiot nie powinien być zdefiniowany w definicji podmiotu, tylko wynika z roli jaką odgrywa w zleceniu, czyli czy jest klientem, czy wykonawcą zadania.
Ale jeśli taka sytuacja będzie wyjątkowo rzadka, lub w ogóle nie występuje (do tej pory) to z uwagi na konieczność definiowania różnych właściwości/cech dla obu rodzajów podmiotów można także posiadać osobne struktury na ich przetrzymywanie. Bo może dla pracowników trzeba będzie później trzymać jakieś harmonogramy, dostępność, kadry (czyli urlopy, zwolnienia, ...), czego nie ma sensu definiować dla klienta.

  1. podczas zapisu kontrahenta będę mu nadawać właściwości:
    • "osoba fizyczna" lub "firma" wówczas wypełniam odpowiednio rekordy "nazwa firmy", "imię", "nazwisko", "NIP", "Regon" lub wpisuje do nich wartość "NULL"
    • "klient" lub "zleceniobiorca" albo "klient" i "zleceniobiorca"

Patrz wyżej. Jeśli oba typy podmiotów będziesz trzymał w jednej tabeli, to podpunkt pierwszy ok, drugi j.w. wg mnie powinien wynikać z roli w zleceniu. Inaczej jeśli klient będzie chciał stać się zleceniobiorcą, będziesz musizał umożliwić komuś przeedytowanie wpisu o tym podmiocie.
Jeśli już to stworzyłbym możliwość grupowania podmiotów, wystarczy płaski słownik. Czyli możesz zdefiniować grupę podmiotów "Zleceniobiorcy", kolejną "Klienci", "Klienci VIP", ...
Na gui domyślnie jako kient pozwalasz wybierać z gr. "klienci", a zleceniodawcę z grupy "Zleceniodawcy", ale dajesz też możliwość zmiany grupy, czy pokazania wszystkich podmiotów. Podmiot powinien móc należeć do wielu grup.

Struktura bazy

  • o typie kontahenta już pisałem powyżej, jako słownik grup
  • twoja "grupa" to wg mnie typ podmiotu, ale to kosmetyka nazewnictwa
  • w adresie jeszcze pole poczta, bo np. adres (miasto) to Kozia Wólka, ale poczta jest w Pierdziszewie
  • kontrahent/adres - albo w tej tabeli dodasz jeszcze typ adresu, zamieszkania/zameldowania, korespondencyjny, ...
    - albo w tabeli kontrahent możesz mieć dwa klucze obce do adres zamieszkania i adres korespondencyjny
  • kontrahent/tel i kontrahent/email - może też warto by mieć tu jakiś typ tego kontaktu, tzn. tel służbowy, komórkowy, sekretariat firmy, dział finansowy, ...
0

Dzięki za cenne rady, jednego nie rozumie:

Jeśli już to stworzyłbym możliwość grupowania podmiotów, wystarczy płaski słownik. Czyli możesz zdefiniować grupę podmiotów "Zleceniobiorcy", kolejną "Klienci", "Klienci VIP", ...
Na gui domyślnie jako kient pozwalasz wybierać z gr. "klienci", a zleceniodawcę z grupy "Zleceniodawcy", ale dajesz też możliwość zmiany grupy, czy pokazania wszystkich podmiotów. Podmiot powinien móc należeć do wielu grup.

O co chodzi z tym "płaskim słownikiem"?

Wg. mnie moje rozwiązanie odpowiada Twojemu, tylko występuje różnica w nazwach tzn. Ty masz "grupa podmiotów" (bardziej trafnie ode mnie), a ja "typ"

typ
id | nazwa
1 | klient
2 | zleceniobiorca

kontrahent/typ
id kontrahenta | id typ

Kiedyś trzeba udostępnić możliwość przypisania kontrahenta do danej grupy i to właśnie miałem na myśli pisząc:

  1. podczas zapisu kontrahenta będę mu nadawać właściwości:
    ...
    • "klient" lub "zleceniobiorca" albo "klient" i "zleceniobiorca"
0

W tej chwili mam coś takiego:

 
abstract class BusinessEntity
    {
        protected List<Address> _address = new List<Address>();
        protected List<Bank> _bank = new List<Bank>();
        protected List<Email> _email = new List<Email>();
        protected List<Telephone> _telephone = new List<Telephone>();

        public string Id
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public string ShortName
        {
            get { throw new System.NotImplementedException(); }
            set {  }
        }

        public string FirstName
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public string Surname
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public string NIP
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public List<Address> Address
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public Enum Group
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public List<Telephone> Tepephone
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public List<Email> Email
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public List<Bank> Bank
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public void AddAddress(Address address)
        {
            if(_address.Contains(address))
                return;
            _address.Add(address);
        }

        public void AddBank(Bank bank)
        {
            if(_bank.Contains(bank))
                return;
            _bank.Add(bank);
        }

        public void AddEmail(Email email)
        {
            if (_email.Contains(email))
                return;
            _email.Add(email);
        }

        public void AddTelephone(Telephone telephone)
        {
            if (_telephone.Contains(telephone))
                return;
            _telephone.Add(telephone);
        }
    }

Stworzyłem struktury: "Email", "Telephone", "Bank" na wzór poniżej przedstawionej klasy "Address" (dopiero teraz zorientowałem się że Address jest klasą a reszta strukturą. Lepiej wszystko (Email, Telephone, Bank, Address) zmienić na klasy czy na struktury?

class Address
    {
        private string id;
        private string postCode;
        private string city;
        private string street;
        private string hauseNumber;
        private string post;
        private string type;

        public int Id
        {
            get { throw new System.NotImplementedException(); }
            set { }
        }

        public string PostCode
        {
            get { return postCode; }
            set { postCode = value; }
        }

        public string City
        {
            get { return city; }
            set { city = value; }
        }

        public string Street
        {
            get { return street; }
            set { street = value; }
        }

        public string HauseNumber
        {
            get { return hauseNumber; }
            set { hauseNumber = value; }
        }

        public string Post
        {
            get { return post; }
            set { post = value; }
        }

        public Address(string postCode_, string city_, string street_, string hauseNumber_, string post_)
        {
            this.postCode = postCode_;
            this.city = city_;
            this.street = street_;
            this.hauseNumber = hauseNumber_;
            this.post = post_;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj is Address)
            {
                Address other = (Address)obj;
                return this.postCode == other.postCode && this.street == other.street && this.hauseNumber == other.hauseNumber;
            }
            return base.Equals(obj);
        }   
    }

Mam zamiar stworzyć jeszcze klasy: CounterParty i Employee dziedziczące po BusinessEntity, coś w ten deseń:

 
class CounterParty: BusinessEntity
    {
        
        public string CompanyName
        {
            get;
            set;
        }

        public CounterParty(string name_, string surname_, string NIP_, Email email_)
        {
            this.FirstName = name_;
            this.Surname = surname_;
            this.NIP = NIP_;
            
           // this._email = email_;
            //this.Email = email_;
        }
        
    }

Nie wiem czy dobrze kombinuje i jak rozwiązać problem z uzupełnianiem listy i dodawanie np. kolejnego adresu email dla podmiotu itd.
Na razie mam coś takiego.

List<CounterParty> counterParty = new List<CounterParty>();
counterParty.Add(new CounterParty("imie", "nazwisko", "765 456 654", new Email("[email protected]", "prywatny")));

W ogóle nie wiem jak podejść do problemu definiowania podmiotu (dane mają być zapisywane w bazie).

1 użytkowników online, w tym zalogowanych: 0, gości: 1