#!/usr/bin/perl
#
# Author:  Petter Reinholdtsen
# Date:    2005-12-17
# License: GNU Public License v2
#
# Send current info to members and ask for corrections.  Send list of
# all company members to the members in a company.

use strict;
use warnings;

BEGIN {
    # Add script location to include path
    my @p = split(m%/%, $0); pop @p; push @INC, join("/", @p);
}

use Getopt::Std;
use medlemsliste;

my %members;
my %firms;
my @mailinglists;
my %mailinglistmember;
my %opts;
my %whitelist;  # List of emails to send to.  Use for testing.

#my $scriptadmin = "pere\@nuug.no";
# Because of bad handling of Errors-To, send all to medlemsregister
my $scriptadmin = "sekretariat\@nuug.no"; 
my $tlf = "+47 85234290";
my $replyto = "sekretariat\@nuug.no";
my $mailfrom = "Foreningen NUUG <$replyto>";

my $sendmail="/usr/sbin/sendmail";

usage() unless getopts('sf:Fuw:GLp', \%opts);

my $debug = 1 unless $opts{s};

if ($opts{s} && `uname -n` ne "geekbay\n") {
    print "Can only send email on geekbay (.nuug.no), as the mailinglist info is there.\n";
    exit 1;
}

if ($opts{w}) {
    open(WL, $opts{w}) || die "Unable to open whitelist ".$opts{w};
    while (<WL>) {
        chomp;
        s/#.*$//g;
        next if (/^\s*$/);
        $whitelist{$_} = 1;
    }
    close (WL);
}

load_mailinglists();
load_memberslist($opts{f} || "medlemsliste.csv", \&process_member);
email_info();

sub usage {
    print <<EOF;
Usage: $0 [-s] [-f <filename>]
  -s           send email
  -f filename  load database from filename
  -F           use $replyto as envelope from
  -w filename  whitelist, only send email to those listed in filename
  -u           list only those without email
  -G           include information about SAGE membership
  -L           send only to those not paying the membership fee
  -p           don't add reminder about missing membership fee
EOF
    exit 1;
}

sub process_member {
    my $memberinfo = shift;
    if ($memberinfo->{ZUsrMedlemstatus}) {
        my $customerid = $memberinfo->{CustomerNo};
        $members{$customerid} = $memberinfo;

        if ("Medlem under bedrift" eq $memberinfo->{ZUsrMedlemstatus}) {
            my $companyid = $memberinfo->{ZUsrArbeidsgiverNo};

            if (exists $firms{$companyid}) {
                push @{$firms{$companyid}}, $customerid;
            } else {
                $firms{$companyid} = [$customerid];
            }
        }
    }
}

sub get_address {
    my ($indent, $memberinfo) = @_;
    my $str;
    for my $field (qw(Address1 Address2 Address3)) {
        $str .= $indent.$memberinfo->{$field}."\n" if $memberinfo->{$field};
    }
    if (!defined $memberinfo->{PostOffice}) {
        $str .= $indent . "[adresse mangler]\n";
    } else {
    $str .= $indent . $memberinfo->{PostCode}." ".$memberinfo->{PostOffice}."\n";
    }
}

sub load_mailinglists {
    my %lists;
    if ( -x "/usr/lib/mailman/bin/list_lists") {
        for my $listname (`/usr/lib/mailman/bin/list_lists -b`) {
            chomp $listname;
#            print "L: $listname\n";
            $lists{$listname} = 1;
            open(LIST, "/usr/lib/mailman/bin/list_members -p $listname|")
                || die;
            while (<LIST>) {
                chomp;
                $mailinglistmember{$listname}{$_} = 1;
            }
            close(LIST);
            push(@mailinglists, $listname);
        }
    }

    for my $cfg (</usr/local/majordomo/lists/*.config>) {
        my $listname = $cfg;
        $listname =~ s%.*/(.+).config%$1%;
        next if (exists $lists{$listname});
        next unless -f "/usr/local/majordomo/lists/$listname";
        open(LIST, "< /usr/local/majordomo/lists/$listname") or die;
        while (<LIST>) {
            chomp;
            $mailinglistmember{$listname}{$_} = 1;
        }
        close(LIST);
        push(@mailinglists, $listname);
    }
}

sub mailinglist_subscriber {
    my ($emailaddress) = @_;
    my @memberof;
    my @notmemberof;
    return "  Mailingliste-medlemskap ikke kjent, kjører ikke på NUUG-server\n\n"
        unless @mailinglists;
    for my $mailinglist (@mailinglists) {
        if ($mailinglistmember{$mailinglist}{$emailaddress}) {
            push @memberof, $mailinglist;
        } else {
            push @notmemberof, $mailinglist;
        }
    }
    my $str;
    if (@memberof) {
        $str = "  Epostadressen abonnerer på følgende mailinglister under \@nuug.no:\n";
        for my $list (@memberof) {
            $str .= "    $list\n";
        }
    } else {
        $str = "  Epostadressen abonnerer ikke på noen mailingliste under \@nuug.no.\n";
    }
    $str .= "\n";
    return $str;
}

sub invoice_direction {
    my ($inforef) = @_;
    if ($inforef->{ErArbeidsgiver}) {
        if (!$inforef->{EmailAddress} ||
            ( $inforef->{EmailAddress} && $inforef->{ErArbeidsgiver} &&
              $inforef->{Informasjon})
            ) {
            return "    Faktura sendes på EHF hvis tilgjengelig, ellers på PAPIR\n";
        } else {
            return "    Faktura sendes på EHF hvis tilgjengelig, ellers på EPOST\n";
        }
    } else {
        return "    Faktura sendes som eFaktura hvis tilgjengelig, ellers på: EPOST\n";
    }
   
}

sub email_info {
    my $currentperiod = current_membership_period();

    for my $customerid (sort keys %members) {
        my $msg;
        my $memberinfo = $members{$customerid};
        if ($opts{'u'}) {
            next unless (!$memberinfo->{EmailAddress});
        }

        # Only send to people
        next if ($memberinfo->{ZUsrMedlemstatus} and
                 "FIRMAMEDLEM" eq $memberinfo->{ZUsrMedlemstatus});

        my $subject = "Medlemsinformasjon fra foreningen NUUG (#$customerid)";
        my $paid = (($memberinfo->{ZBetaltTil} || "") ge $currentperiod);
        if ($opts{L}) {
            if ($paid) {
                next;
            } else {
                $subject =
                    "Savner kontingentbetaling for ditt medlemskap i NUUG (#$customerid)";
            }
        }

        my $memberaddr = $memberinfo->{Name}. " <".$memberinfo->{EmailAddress} . ">";
        my $headeraddr = " <".$memberinfo->{EmailAddress} . ">";   # jonp 2023-01-03  Avoid potential problem with utf-8 chars in full name
        $msg .= <<EOF;
To: $headeraddr
From: $mailfrom
Errors-to: $scriptadmin
Subject: $subject
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit


Dette er en automatisk generert epost fra foreningen NUUG,
<URL:https://nuug.no/>.  For å sikre at alle medlemmene mottar
informasjon om årsmøte og andre aktiviteter i foreningen og dermed
kvalitetssikre medlemsregisteret, sender vi noen ganger i året ut den
informasjonen vi har notert oss om ditt medlemskap slik at du har
mulighet til å korrigere eventuelle feil.

EOF
        if ( $memberinfo->{ZUsrFakturertPeriode}
             and (!defined $memberinfo->{ZBetaltTil} or
                  $memberinfo->{ZBetaltTil} ne $currentperiod) 
             and ("Æresmedlem" ne $memberinfo->{ZUsrMedlemstatus})  # jonp 2017-01-29
             and !$opts{p}) {
            $msg .= <<EOF;
  KONTINGENT IKKE BETALT

Vi har ikke registrert at kontingenten for ditt medlemskap er betalt.


(Dersom du er innmeldt som nytt medlem og har fått faktura i
løpet av de siste 14 dagene kan du se bort fra denne purringen og
forholde deg istedet til meldinger du har fått ifm. innmelding.
Den nåværende purremekanismen har dessverre ikke noen mulighet
for å skille ut "nyinnmeldte ikke-betalte".)


Hvis du ikke kan finne noen faktura så kan du få en ny kopi fra
sekretariatet ved å sende epost til $replyto, gjerne som svar på
denne eposten.

Hvis kontingenten ikke blir betalt snart vil du bli registrert
som utmeldt av foreningen. Ønsker du ikke lenger å være medlem,
ser vi gjerne at du sender oss en beskjed om utmelding, så
slipper du å motta flere purringer, fakturaer og påminnelser fra
oss.

Ved utmelding vil abonnementet på epostlisten medlemmer\@nuug.no
endres til et abonnement på annonsering\@nuug.no.

EOF
        }
        if ($memberinfo->{ZUsrArbeidsgiver}) {
            my $companycustomno = $memberinfo->{ZUsrArbeidsgiverNo};
            my $companyinfo = $members{$companycustomno};
            if (!$companyinfo->{EmailAddress}) {
                $msg .= <<EOF;
For å redusere kostnadene har NUUG gått over til å sende
kontingentfaktura på epost.  Vær så snill å gi tilbakemelding om
hvilken epostadresse som skal motta fakturaen for bedrifts-
medlemskapet.

EOF
            }
        }

        $msg .= <<EOF;
Her er det vi har notert oss når det gjelder ditt medlemskap:

EOF
        $msg .= "  Navn:          $memberaddr\n";
        $msg .= "  Medlemsnummer: $customerid ".
            "(". $memberinfo->{ZUsrMedlemstatus}.")\n";
#        $msg .= "  USENIX-nummer: ".$memberinfo->{USENIX}."\n";
        $msg .= "  SAGE-medlem\n" if $memberinfo->{'SAGE'};

        $msg .= "  Telefon:       ".$memberinfo->{Telephone}."\n";
        $msg .= "  Mobiltelefon:  ".$memberinfo->{MobileTelephone}."\n";
#       $msg .= "  Medlem siden:  ".$memberinfo->{ZUsrInnmeldtDato}."\n";
        $msg .= "  Motta info     ".
          ($memberinfo->{Informasjon} ? "ja" : "nei") ."\n";

#        $msg .= "  Postadresse som medlem (for utsending av ;login:, årsmøtepapirer mm):\n";
        $msg .= "  Postadresse som medlem:\n";
        $msg .= get_address("    ", $memberinfo);

        if ($memberinfo->{ZUsrArbeidsgiver}) {
            my $companycustomno = $memberinfo->{ZUsrArbeidsgiverNo};
            $msg .= "  Medlemsfirmaets adresse (medlemsnummer $companycustomno):\n";
            my $companyinfo = $members{$companycustomno};

            print STDERR "error: missing company name for member $companycustomno\n"
                unless $companyinfo->{Name};

            $msg .= "    ".($companyinfo->{Name} || "[unknown]")."\n";
            $msg .= get_address("    ", $companyinfo);
            if ($companyinfo->{ZUsrFakturaReferanse}) {
                $msg .= "    Fakturareferanse: " .
                    $companyinfo->{ZUsrFakturaReferanse} . "\n";
            }
            $msg .= "    Kontaktperson: ".
                ($companyinfo->{Kontaktperson} || "[ikke registrert]" )."\n";
            $msg .= "    Epostadresse : ".
                ($companyinfo->{EmailAddress} || "[ikke registrert]" )."\n";
            $msg .= invoice_direction($companyinfo);
            $msg .= "    Organisasjonsnummer: ".($companyinfo->{recipientOrgNo} || "[ikke registrert]" )."\n";
        } else {
            $msg .= invoice_direction($memberinfo);
        }
        $msg .= "\n";

        $msg .= mailinglist_subscriber($memberinfo->{EmailAddress});

        my $sagecount = 0;
        if ($memberinfo->{ZUsrMedlemstatus} and
            "Medlem under bedrift" eq $memberinfo->{ZUsrMedlemstatus} and
            $memberinfo->{ZUsrArbeidsgiverNo} and
            0 < @{$firms{$memberinfo->{ZUsrArbeidsgiverNo}}}) {
            $msg .= <<EOF;
  Alle medlemmene i din bedrift.  Det er fint om du kan sjekke om
  epostadressene er korrekte.

EOF

            $msg .= "    Medl.nr. Navn og epostadresse\n";
            $msg .= "    ------------------------------------------------\n";
            for my $othersid (sort @{$firms{$memberinfo->{ZUsrArbeidsgiverNo}}}) {
                # next if ($othersid == $customerid); # removed by jonp 2009-10-23
                my $othersinfo = $members{$othersid};
                my $othersname = $othersinfo->{Name};
                my $othersemail = $othersinfo->{EmailAddress};
                my $otherssage = "";
                if ($opts{'G'} and $othersinfo->{'SAGE'}) {
                   $otherssage = " SAGE";
                   $sagecount++;
                }
                $msg .= sprintf("    %-8s %s <%s>%s\n",
                                $othersid, $othersname, $othersemail, $otherssage);
            }
            $msg .= "\n";
        }

        if ($memberinfo->{ZUsrMedlemstatus} and
            "Medlem under bedrift" eq $memberinfo->{ZUsrMedlemstatus} and
            $memberinfo->{ZUsrArbeidsgiverNo}) {
            my $firmlimit = firmmembers_included();
            my $firmcount = @{$firms{$memberinfo->{ZUsrArbeidsgiverNo}}};
            if ($firmcount < $firmlimit) {
                $msg .= <<EOF;
Et firmamedlemskap inkluderer $firmlimit personer under bedriften uten
ekstra kostnader.  Ditt firma bruker kun $firmcount av disse plassene.

EOF
            } else {
                $msg .= <<EOF;
Totalt $firmcount personer, hvorav $firmlimit er inkludert i firmamedlemskapet.

EOF
            }
            if ($opts{'G'}) {
               $msg .= <<EOF;
$sagecount personer er også medlemmer i SAGE.

EOF
            }

        }
        $msg .= <<EOF;
Gjelder kun personlige medlemmer og studenter: Faktura sendes som eFaktura hvis
mulig. Det vil hjelpe for identifikasjon hvis det oppgitte mobilnummeret er
registrert i VIPPS.

For bedriftsmedlemmer gjelder at faktura sendes som EHF hvis vi har registrert
organisasjonsnummeret og bedriften har åpnet for EHF gjennom sitt regnskapssystem.

Hvis du ønsker å melde deg ut eller hvis noe bør korrigeres,
ta kontakt med sekretariatet på epost til $replyto.
Det er i tillegg mulig å bruke innmeldingsskjemaet som er
tilgjengelig fra <URL:https://nuug.no/innmelding.shtml>.
Husk å opplyse om medlemsnummer når du melder inn korreksjoner.

Oppdatering av epostlister gjør medlemmene selv.  Instruksjoner finnes på
<URL:https://nuug.no/mailarkiv/>.  Et unntak er epostlisten
medlemmer\@nuug.no som oppdateres automatisk fra medlemsregisteret.

Vennlig hilsen,
-- 
Styret og sekretariatet i NUUG ved
leder Thomas Hansen
EOF
        if ($memberinfo->{EmailAddress}) {
            send_email($memberinfo->{EmailAddress}, $msg)
                unless ($opts{w} and
                        ! $whitelist{$memberinfo->{EmailAddress}});
        } else {
            print STDERR "error: unable to send to member $customerid, email address is missing\n";
            print STDERR $msg;
            print STDERR "======================================================================\n";
        }
    }
}
sub send_email {
    my ($address, $text) = @_;
    if ($debug) {
        print "$text";
        print "======================================================================\n";
    } else {
        print STDERR "info: sending email to $address\n";
        if ($opts{F}) {
            open(SENDMAIL, "|$sendmail -t -f $replyto") or die "Unable to run $sendmail";
        } else {
            open(SENDMAIL, "|$sendmail -t") or die "Unable to run $sendmail";
        }
        print SENDMAIL $text;
        close(SENDMAIL);
    }
}
