internal final class NW_PurchAgreementHelper
{
    public static PurchAgreementId CreatePA(NW_SigningContract contract)
    {
        AgreementHeaderDefault agreementHeaderDefault;
        PurchAgreementHeader purchAgreementHeader;
        PurchAgreementHeaderDefault purchAgreementHeaderDefault;
        PurchAgreementFormDatasourceManager Manager;
        Common  purchSalesagreementHeaderDefault;
        PurchAgreementId tmpAgreementId;
        NumberSeq num;
        NW_SigningContractLine  NW_SigningContractLine;

        num = NumberSeq::newGetNum(PurchParameters::numRefPurchAgreementId());
        tmpAgreementId = num.num();
        VendTable VendTable = VendTable::find(contract.VendAccount);
        purchAgreementHeader.clear();
        purchAgreementHeader.initValue();
        purchAgreementHeader.VendAccount = contract.VendAccount;
        purchAgreementHeader.initFromVendTable();
        purchAgreementHeader.AgreementDescription= contract.AgreementDescription;
        purchAgreementHeader.PurchNumberSequence = tmpAgreementId;
        purchAgreementHeader.DocumentTitle = tmpAgreementId;
        purchAgreementHeader.DefaultAgreementLineType = CommitmentType::ProductCategory;
        purchAgreementHeader.DefaultAgreementLineEffectiveDate = contract.DefaultAgreementLineEffectiveDate;
        purchAgreementHeader.DefaultAgreementLineExpirationDate = contract.DefaultAgreementLineExpirationDate;
        purchAgreementHeader.NADepartment = contract.NADepartment;

        agreementHeaderDefault.clear();
        agreementHeaderDefault.initValue();

        purchAgreementHeaderDefault.clear();
        purchAgreementHeaderDefault.initValue();

        purchAgreementHeader.doInsert(); // skip insert code
        agreementHeaderDefault.initFromVendTable(VendTable);
        agreementHeaderDefault.AgreementHeader = purchAgreementHeader.RecId;
        agreementHeaderDefault.insert();
        purchAgreementHeaderDefault.initFromVendTable(VendTable);
        purchAgreementHeaderDefault.PurchaseAgreementHeader = purchAgreementHeader.RecId;
        purchAgreementHeaderDefault.insert();

        // copy attatchement 
        Docu::copy(contract, purchAgreementHeader);

        //lines
        AgreementLine agreementLine;
        //AgreementLineQuantityCommitment agreementLineQuantity;
        AgreementLineVolumeCommitment agreementLineVolume;
        AgreementLineDefault agreementLineDefault;
        InventDimId inventDimId = InventDim::findOrCreateBlank().inventDimId;

        while select NW_SigningContractLine
            where NW_SigningContractLine.HeaderRequestId == contract.RequestId
        {
            //RecId category = 5637147352;
            
            agreementLineVolume.clear();
            agreementLineVolume.Agreement = purchAgreementHeader.RecId;
            agreementLineVolume.Category = NW_SigningContractLine.Category;
            agreementLineVolume.InventDimId = inventDimId;
            agreementLineVolume.InventDimDataAreaId = curExt();
            agreementLineVolume.LineDiscountPercent = NW_SigningContractLine.LineDiscountPercent;
            agreementLineVolume.CommitedAmount = NW_SigningContractLine.CommitedAmount;
            agreementLineVolume.EffectiveDate = NW_SigningContractLine.EffectiveDate;
            agreementLineVolume.ExpirationDate = NW_SigningContractLine.ExpirationDate;
            agreementLineVolume.DefaultDimension = NW_SigningContractLine.DefaultDimension;
            agreementLineVolume.insert();

            //agreementLineDefault.ProjectActivityNumberDataAreaId = companyView.id;
            agreementLineDefault.AgreementLine = agreementLineVolume.RecId;
            //agreementLineDefault.ProjectCategoryDataAreaId = companyView.id;
            //agreementLineDefault.SalesCommissionGroupDataAreaId = companyView.id;
            //agreementLineDefault.SalesModeOfDeliveryDataAreaId = companyView.id;
            agreementLineDefault.insert();
        }
        return tmpAgreementId;
    }

    public static void CancelPA(PurchAgreementId Id)
    {
        PurchAgreementHeader    PurchAgreementHeader;
        ttsbegin;
        select forupdate PurchAgreementHeader where PurchAgreementHeader.PurchNumberSequence == Id;
        PurchAgreementHeader.AgreementState = AgreementState::Closed;
        PurchAgreementHeader.update();
        ttscommit;
    }

    public static void ChangePA(PurchAgreementId Id, NW_SigningContract contract)
    {
        NW_SigningContractLine  NW_SigningContractLine;
        PurchAgreementHeader    PurchAgreementHeader;

        ttsbegin;
        select forupdate PurchAgreementHeader where PurchAgreementHeader.PurchNumberSequence == Id;
        PurchAgreementHeader.DefaultAgreementLineEffectiveDate = contract.DefaultAgreementLineEffectiveDate;
        PurchAgreementHeader.DefaultAgreementLineExpirationDate = contract.DefaultAgreementLineExpirationDate;
        PurchAgreementHeader.NADepartment = contract.NADepartment;
        PurchAgreementHeader.update();
        ttscommit;
        // lines
        AgreementLine agreementLine;
        //AgreementLineQuantityCommitment agreementLineQuantity;
        AgreementLineVolumeCommitment agreementLineVolume;
        AgreementLineDefault agreementLineDefault;
        InventDimId inventDimId = InventDim::findOrCreateBlank().inventDimId;
        ttsbegin;
        while select NW_SigningContractLine
            where NW_SigningContractLine.HeaderRequestId == contract.RequestId
        {
            if(NW_SigningContractLine.AgreementRecId) // updare
            {
                select forupdate agreementLineVolume where agreementLineVolume.RecId == NW_SigningContractLine.AgreementRecId;
                agreementLineVolume.CommitedAmount = NW_SigningContractLine.CommitedAmount;
                agreementLineVolume.EffectiveDate = NW_SigningContractLine.EffectiveDate;
                agreementLineVolume.ExpirationDate = NW_SigningContractLine.ExpirationDate;
                agreementLineVolume.DefaultDimension = NW_SigningContractLine.DefaultDimension;
                agreementLineVolume.update();
            }
            else //insert
            {
                agreementLineVolume.clear();
                agreementLineVolume.Agreement = purchAgreementHeader.RecId;
                agreementLineVolume.Category = NW_SigningContractLine.Category;
                agreementLineVolume.InventDimId = inventDimId;
                agreementLineVolume.InventDimDataAreaId = curExt();
                agreementLineVolume.LineDiscountPercent = NW_SigningContractLine.LineDiscountPercent;
                agreementLineVolume.CommitedAmount = NW_SigningContractLine.CommitedAmount;
                agreementLineVolume.EffectiveDate = NW_SigningContractLine.EffectiveDate;
                agreementLineVolume.ExpirationDate = NW_SigningContractLine.ExpirationDate;
                agreementLineVolume.DefaultDimension = NW_SigningContractLine.DefaultDimension;
                agreementLineVolume.insert();

                agreementLineDefault.AgreementLine = agreementLineVolume.RecId;
                agreementLineDefault.insert();
            }
        }
        ttscommit;
    }

    public static void SendEmailGeneratedPA(str Id)
    {
        NW_ProcurmentEmailSetup EmailSetup;
        NW_SigningContract          contract;
        Email                       ToEmail;
        select EmailSetup
            where EmailSetup.NW_ProcurmentEmailTypes == NW_ProcurmentEmailTypes::GeneratedPA;
        select firstonly contract where contract.RequestId == Id;
        if(EmailSetup)
        {
            str body="";
            SysMailerMessageBuilder builder = new SysMailerMessageBuilder();
            Body=EmailSetup.jobAdText;
            Body=strReplace(Body,"{RequestId}", contract.RequestId);
            Body=strReplace(Body,"{AgreementId}", contract.PurchNumberSequence);
            Body=strReplace(Body,"{Type}", enum2Str(contract.ContractType));
            Body=strReplace(Body,"{VendorName}", contract.vendName());
            Body=strReplace(Body,"{EffectiveDate}", any2Str(contract.DefaultAgreementLineEffectiveDate));
            Body=strReplace(Body,"{ExpirationDate}",any2Str(contract.DefaultAgreementLineExpirationDate));
            builder.setSubject(EmailSetup.Subject);
            builder.setBody(body,true);
            builder.setFrom(EmailSetup.Sender);
            builder.addTo(VendTable::find(contract.VendAccount).email());
            SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(builder.getMessage());
        }
    }

    public static void SendEmailSendSigningToVendor(str Id)
    {
        NW_ProcurmentEmailSetup EmailSetup;
        NW_SigningContract          contract;
        Email                       ToEmail;
        select EmailSetup
            where EmailSetup.NW_ProcurmentEmailTypes == NW_ProcurmentEmailTypes::SendSigningToVendor;
        select firstonly contract where contract.RequestId == Id;
        if(EmailSetup)
        {
            str body="";
            SysMailerMessageBuilder builder = new SysMailerMessageBuilder();
            Body=EmailSetup.jobAdText;
            Body=strReplace(Body,"{RequestId}", contract.RequestId);
            Body=strReplace(Body,"{AgreementId}", contract.PurchNumberSequence);
            Body=strReplace(Body,"{Type}", enum2Str(contract.ContractType));
            Body=strReplace(Body,"{VendorName}", contract.vendName());
            Body=strReplace(Body,"{EffectiveDate}",any2Str(contract.DefaultAgreementLineEffectiveDate));
            Body=strReplace(Body,"{ExpirationDate}",any2Str(contract.DefaultAgreementLineExpirationDate));
            builder.setSubject(EmailSetup.Subject);
            builder.setBody(body,true);
            builder.setFrom(EmailSetup.Sender);
            builder.addTo(VendTable::find(contract.VendAccount).email());
            SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(builder.getMessage());
        }
    }

    public static void SendEmailVendorAction(str Id)
    {
        NW_ProcurmentEmailSetup EmailSetup;
        NW_SigningContract          contract;
        Email                       ToEmail;
        select EmailSetup
            where EmailSetup.NW_ProcurmentEmailTypes == NW_ProcurmentEmailTypes::VendorAction;
        select firstonly contract where contract.RequestId == Id;
        if(EmailSetup)
        {
            str body="";
            SysMailerMessageBuilder builder = new SysMailerMessageBuilder();
            Body=EmailSetup.jobAdText;
            Body=strReplace(Body,"{RequestId}", contract.RequestId);
            Body=strReplace(Body,"{AgreementId}", contract.PurchNumberSequence);
            Body=strReplace(Body,"{Type}", enum2Str(contract.ContractType));
            Body=strReplace(Body,"{VendorName}", contract.vendName());
            Body=strReplace(Body,"{EffectiveDate}",any2Str(contract.DefaultAgreementLineEffectiveDate));
            Body=strReplace(Body,"{ExpirationDate}",any2Str(contract.DefaultAgreementLineExpirationDate));
            builder.setSubject(EmailSetup.Subject);
            builder.setBody(body,true);
            builder.setFrom(EmailSetup.Sender);
            builder.addTo(VendTable::find(contract.VendAccount).email());
            SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(builder.getMessage());
        }
    }

}