Spostamento cartelle sorgenti in src

git-svn-id: svn://10.65.10.50/branches/R_10_00@23232 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
mtollari 2016-09-09 13:52:18 +00:00
parent 0c0d2fc2f4
commit aa9add1b1a
8827 changed files with 2121413 additions and 0 deletions

View File

@ -0,0 +1,115 @@
/****************************** Module Header ******************************\
* Module Name: CppWindowsService.cpp
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* The file defines the entry point of the application. According to the
* arguments in the command line, the function installs or uninstalls or
* starts the service by calling into different routines.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma region Includes
#include "EsignService.h"
#include "ServiceInstaller.h"
#pragma endregion
//
// Settings of the service
//
// Internal name of the service
#define SERVICE_NAME TEXT("ESignService")
// Displayed name of the service
#define SERVICE_DISPLAY_NAME TEXT("Sirio Digital signature service")
// Service start options.
#define SERVICE_TYPE SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS
// Service start options.
#define SERVICE_START_TYPE SERVICE_AUTO_START
// List of service dependencies - "dep1\0dep2\0\0"
#define SERVICE_DEPENDENCIES TEXT("")
// The name of the account under which the service should run
//#define SERVICE_ACCOUNT TEXT("NT AUTHORITY\\LocalService")
#define SERVICE_ACCOUNT NULL
// The password to the service account name
#define SERVICE_PASSWORD NULL
//
// FUNCTION: wmain(int, wchar_t *[])
//
// PURPOSE: entrypoint for the application.
//
// PARAMETERS:
// argc - number of command line arguments
// argv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// wmain() either performs the command line task, or run the service.
//
int wmain(int argc, wchar_t *argv[])
{
if ((argc > 1) && ((*argv[1] == L'-' || (*argv[1] == L'/'))))
{
if (_wcsicmp(L"install", argv[1] + 1) == 0)
{
if (InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_TYPE, // Service type
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
))
StartService(SERVICE_NAME);
}
else if (_wcsicmp(L"remove", argv[1] + 1) == 0 || _wcsicmp(L"uninstall", argv[1] + 1) == 0)
{
UninstallService(SERVICE_NAME);
}
else if (_wcsicmp(L"start", argv[1] + 1) == 0)
{
StartService(SERVICE_NAME);
}
else if (_wcsicmp(L"stop", argv[1] + 1) == 0)
{
StopService(SERVICE_NAME);
}
else if (_wcsicmp(L"restart", argv[1] + 1) == 0)
{
StopService(SERVICE_NAME);
::Sleep(1000);
StartService(SERVICE_NAME);
}
}
else
{
CESignService service(SERVICE_NAME);
if (!CServiceBase::Run(service))
{
printf("ESignService 1.4 %s\n", __TIMESTAMP__);
printf("Parameters: -install -start -stop -restart -remove\n");
printf("Running as standard process from command line\n");
service.ServiceLoop();
}
}
return 0;
}

View File

@ -0,0 +1,391 @@
#pragma region Includes
#include "ESignService.h"
#include "ThreadPool.h"
#include "PathName.h"
#include <cassert>
#include <zmq.h>
#include <Wtsapi32.h>
#pragma comment(lib, "Wtsapi32.lib")
#pragma endregion
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
static errno_t GetIniString(const char* key, gt_string val)
{
::GetPrivateProfileStringA("Default", key, "", val, sizeof(gt_string), "./esigner.ini");
return *val ? 0 : EINVAL;
}
static int GetIniInteger(const char* key)
{
gt_string val = { 0 };
GetIniString(key, val);
return atoi(val);
}
///////////////////////////////////////////////////////////
// CESignService
///////////////////////////////////////////////////////////
CESignService::CESignService(LPCTSTR pszServiceName, BOOL fCanStop, BOOL fCanShutdown, BOOL fCanPauseContinue)
: CServiceBase(pszServiceName, fCanStop, fCanShutdown, fCanPauseContinue)
{
m_fStopping = FALSE;
// Create a manual-reset event that is not signaled at first to indicate
// the stopped signal of the service.
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hStoppedEvent == NULL)
throw GetLastError();
}
CESignService::~CESignService(void)
{
if (m_hStoppedEvent)
{
CloseHandle(m_hStoppedEvent);
m_hStoppedEvent = NULL;
}
}
//
// FUNCTION: CESignService::OnStart(DWORD, LPWSTR *)
//
// PURPOSE: The function is executed when a Start command is sent to the
// service by the SCM or when the operating system starts (for a service
// that starts automatically). It specifies actions to take when the
// service starts. In this code sample, OnStart logs a service-start
// message to the Application log, and queues the main service function for
// execution in a thread pool worker thread.
//
// PARAMETERS:
// * dwArgc - number of command line arguments
// * lpszArgv - array of command line arguments
//
// NOTE: A service application is designed to be long running. Therefore,
// it usually polls or monitors something in the system. The monitoring is
// set up in the OnStart method. However, OnStart does not actually do the
// monitoring. The OnStart method must return to the operating system after
// the service's operation has begun. It must not loop forever or block. To
// set up a simple monitoring mechanism, one general solution is to create
// a timer in OnStart. The timer would then raise events in your code
// periodically, at which time your service could do its monitoring. The
// other solution is to spawn a new thread to perform the main service
// functions, which is demonstrated in this code sample.
//
void CESignService::OnStart(DWORD dwArgc, LPWSTR *lpszArgv)
{
// Log a service start message to the Application log.
WriteEventLogEntry(TEXT("ESignService Starting"));
// Queue the main service function for execution in a worker thread.
CThreadPool::QueueUserWorkItem(&CESignService::ServiceLoop, this);
}
char CESignService::ParseHex(const char* hex) const
{
int n = 0;
sscanf_s(hex, "%2X", &n);
return char(n);
}
const char* CESignService::ParseString(const char* equal, gt_string str) const
{
gt_strcpy(str, "");
const char* s = equal;
int i = 0;
for (; *s != '&' && *s > ' '; s++)
{
if (*s == '%')
{
const char h = ParseHex(s+1);
gt_chrcat(str, h);
s += 2;
}
else
gt_chrcat(str, *s);
}
return s;
}
const char* CESignService::ParseString(const char* equal, CPathName& path) const
{
gt_string str = { 0 };
const char* s = ParseString(equal, str);
path.Set(str);
return s;
}
bool CESignService::ParseGET(const char* get, CPathName& src, CPathName& dst, CPathName& bck,
gt_string pin, gt_string ext) const
{
src = dst = bck = "";
gt_strcpy(pin, "");
gt_strcpy(ext, "");
while (get != NULL)
{
const char* equal = strchr(get, '=');
if (equal != NULL)
{
if (*(equal-1) > 'Z')
break;
switch (*(equal-3))
{
case 'B': get = ParseString(equal+1, bck); break; // BCK
case 'D': get = ParseString(equal+1, dst); break; // DST
case 'E': get = ParseString(equal+1, ext); break; // EXT
case 'P': get = ParseString(equal+1, pin); break; // PIN
case 'S': get = ParseString(equal+1, src); break; // SRC
default : get = equal+1; break;
}
}
else
get = equal;
}
return !src.empty();
}
/*
DWORD CESignService::RunAsync(const char* strCmdLine) const
{
DWORD ret = ::WinExec(strCmdLine, SW_SHOWDEFAULT);
if (ret >= 32)
{
ret = 0;
}
else
{
LPWSTR messageBuffer = NULL;
ret = ::GetLastError();
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, ret, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
WriteEventLogEntry(messageBuffer, EVENTLOG_ERROR_TYPE, ret);
LocalFree(messageBuffer);
}
return ret;
}
*/
DWORD CESignService::RunSync(const char* strCmdLine) const
{
STARTUPINFOA si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
si.lpDesktop = "winsta0\\default";
si.wShowWindow = SW_SHOW;
DWORD activeSessionId = ::WTSGetActiveConsoleSessionId();
HANDLE currentToken = NULL; ::WTSQueryUserToken(activeSessionId, &currentToken);
DWORD err = 0;
if (currentToken)
{
::CreateProcessAsUserA(currentToken, NULL,
(LPSTR)strCmdLine, // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
FALSE, // no Handle inheritance
NORMAL_PRIORITY_CLASS, // creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si,
&pi);
}
else
{
::CreateProcessA(NULL,
(LPSTR)strCmdLine, // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
FALSE, // no Handle inheritance
NORMAL_PRIORITY_CLASS, // creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si,
&pi);
}
if (pi.hProcess)
{
::WaitForSingleObject(pi.hProcess, INFINITE);
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
}
else
err = ::GetLastError();
if (currentToken)
{
::CloseHandle(currentToken);
currentToken = NULL;
}
return err;
}
void AppendVar(gt_string cmd, const char* var, const char* val)
{
if (val && *val)
{
gt_chrcat(cmd, ' ');
gt_strcat(cmd, var);
gt_chrcat(cmd, '=');
if (*val != '"' && strchr(val, ' '))
{
gt_chrcat(cmd, '"');
gt_strcat(cmd, val);
gt_chrcat(cmd, '"');
}
else
gt_strcat(cmd, val);
}
}
//
// FUNCTION: CESignService::ServiceLoop(void)
//
// PURPOSE: The method performs the main function of the service. It runs
// on a thread pool worker thread.
//
void CESignService::ServiceLoop(void)
{
void *ctx = zmq_ctx_new ();
assert (ctx);
/* Create ZMQ_STREAM socket */
void *socket = zmq_socket (ctx, ZMQ_STREAM);
assert (socket);
int nPort = GetIniInteger("PORT");
if (nPort < 1000)
nPort = 8083;
char port[32]; sprintf_s(port, sizeof(port), "tcp://*:%d", nPort);
int rc = zmq_bind (socket, port);
assert (rc == 0);
const int timeout = 5000; // 5 secondi di timeout per verificare anche m_fStopping
zmq_setsockopt (socket, ZMQ_RCVTIMEO, &timeout, sizeof(timeout));
/* Data structure to hold the ZMQ_STREAM ID */
uint8_t id [256];
/* Data structure to hold the ZMQ_STREAM received data */
const size_t raw_max = 1024;
char* raw = new char[raw_max];
while (!m_fStopping)
{
/* Get HTTP request; ID frame and then request */
memset(id, 0, sizeof(id));
const int id_size = zmq_recv (socket, id, sizeof(id), 0);
if (id_size <= 0)
continue;
memset(raw, 0, raw_max);
const size_t raw_size = zmq_recv (socket, raw, raw_max, 0);
CPathName src, dst, bck;
gt_string pin = { 0 }, ext = { 0 };
ParseGET(raw, src, dst, bck, pin, ext);
/* Sends the ID frame followed by the response */
zmq_send (socket, id, id_size, ZMQ_SNDMORE);
gt_string log = {0};
gt_strcpy(log, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n");
CPathName pdf; pdf.Set(src, "*", "pdf");
const int nTotal = pdf.Count();
if (nTotal > 0)
{
const char* const cmdfile = "ESignCmd.exe";
const char* const logfile = "ESignCmd.log";
gt_string cmd = { 0 };
gt_strcpy(cmd, cmdfile);
AppendVar(cmd, "SRC", src);
AppendVar(cmd, "DST", dst);
AppendVar(cmd, "BCK", bck);
AppendVar(cmd, "LOG", logfile);
AppendVar(cmd, "PIN", pin);
AppendVar(cmd, "EXT", ext);
const DWORD err = RunSync(cmd);
memset(raw, 0, raw_max);
if (err == 0)
{
FILE* log = NULL;
if (fopen_s(&log, logfile, "r") == 0)
{
fread(raw, raw_max-1, 1, log);
fclose(log); log = NULL;
}
else
sprintf_s(raw, raw_max,
"%s: bloccato nella firma di %d documenti.",
cmdfile, nTotal);
}
else
sprintf_s(raw, raw_max,
"%s: errore 0x%X nella firma di %d documenti.",
cmdfile, err, nTotal);
gt_strcat(log, raw);
}
else
{
gt_strcat(log, "Non ci sono documenti da firmare!\r\n");
}
zmq_send (socket, log, strlen(log), ZMQ_SNDMORE);
/* Closes the connection by sending the ID frame followed by a zero response */
zmq_send (socket, id, id_size, ZMQ_SNDMORE);
zmq_send (socket, 0, 0, ZMQ_SNDMORE);
/* NOTE: If we don't use ZMQ_SNDMORE, then we won't be able to send more */
/* message to any client */
}
delete [] raw;
zmq_close (socket);
zmq_ctx_destroy (ctx);
// Signal the stopped event.
SetEvent(m_hStoppedEvent);
}
//
// FUNCTION: CESignService::OnStop(void)
//
// PURPOSE: The function is executed when a Stop command is sent to the
// service by SCM. It specifies actions to take when a service stops
// running. In this code sample, OnStop logs a service-stop message to the
// Application log, and waits for the finish of the main service function.
//
// COMMENTS:
// Be sure to periodically call ReportServiceStatus() with
// SERVICE_STOP_PENDING if the procedure is going to take long time.
//
void CESignService::OnStop()
{
// Log a service stop message to the Application log.
WriteEventLogEntry(L"ESignService Stopping");
// Indicate that the service is stopping and wait for the finish of the
// main service function (ServiceWorkerThread).
m_fStopping = TRUE;
if (::WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
throw ::GetLastError();
}

View File

@ -0,0 +1,50 @@
/****************************** Module Header ******************************\
* Module Name: SampleService.h
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* Provides a sample service class that derives from the service base class -
* CServiceBase. The sample service logs the service start and stop
* information to the Application event log, and shows how to run the main
* function of the service in a thread pool worker thread.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma once
#include "ServiceBase.h"
#include "PathName.h"
class CESignService : public CServiceBase
{
private:
BOOL m_fStopping;
HANDLE m_hStoppedEvent;
protected:
virtual void OnStart(DWORD dwArgc, PWSTR *pszArgv);
virtual void OnStop();
char ParseHex(const char* hex) const;
const char* ParseString(const char* s, gt_string str) const;
const char* ParseString(const char* equal, CPathName& path) const;
bool ParseGET(const char* get, CPathName& src, CPathName& dst,
CPathName& bck, gt_string pin, gt_string ext) const;
DWORD RunAsync(const char* strCmdLine) const;
DWORD RunSync(const char* strCmdLine) const;
public:
CESignService(LPCTSTR pszServiceName, BOOL fCanStop = TRUE,
BOOL fCanShutdown = TRUE, BOOL fCanPauseContinue = FALSE);
void ServiceLoop(void);
virtual ~CESignService();
};

View File

@ -0,0 +1,39 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Firma Digitale Esigner</title>
</head>
<body>
<form action="http://127.0.0.1:8083/esign" method="get" target="Result" >
<table bgcolor="LightBlue ">
<caption style="background:LightCyan">Firma digitale documenti PDF</caption>
<tr>
<td>Cartella o documento da firmare:</td>
<td><input type="text" name="SRC" size="80" maxlenght="256"/></td>
</tr>
<tr>
<td>Cartella di destinazione dei documenti firmati:</td>
<td><input type="text" name="DST" size="80" maxlenght="256"/></td>
</tr>
<tr>
<td>Cartella di backup dei documenti originali:</td>
<td><input type="text" name="BCK" size="80" maxlenght="256"/></td>
</tr>
<tr>
<td colspan="2"><hr/></td>
</tr>
<tr>
<td>PIN o password:</td>
<td><input type="password" name="PIN" size="8" maxlenght="8" />
<input type="submit" value="Firma documenti" />
</td>
</tr>
<tr>
<td colspan="2">
<iframe width="100%%" height="480" style="background:LightCyan" name="Result" />
</td>
</tr>
</table>
</form>
</body>
</html>

View File

@ -0,0 +1,257 @@
#pragma region Includes
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include "PathName.h"
#include <cassert>
#include <stdlib.h>
#pragma endregion
///////////////////////////////////////////////////////////
// utility
///////////////////////////////////////////////////////////
char* wstring2string(const wchar_t* wstr)
{
static char str[1024];
::WideCharToMultiByte(CP_ACP, WC_SEPCHARS, wstr, -1, str, sizeof(str), NULL, NULL);
return str;
}
wchar_t* string2wstring(const char* str)
{
static wchar_t wstr[1024];
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, 1024);
return wstr;
}
///////////////////////////////////////////////////////////
// CPathName
///////////////////////////////////////////////////////////
static gt_string __tmp;
errno_t gt_strcpy(gt_string dst, const char* str)
{
assert(dst);
errno_t e = 0;
if (str && *str)
e = ::strcpy_s(dst, sizeof(gt_string), str);
else
*dst = '\0';
return e;
}
errno_t gt_strcat(gt_string dst, const char* str)
{
assert(dst);
errno_t e = 0;
if (str && *str)
e = ::strcat_s(dst, sizeof(gt_string), str);
return e;
}
errno_t gt_chrcat(gt_string dst, const char chr)
{
char s[2] = { chr, '\0' };
return gt_strcat(dst, s);
}
bool gt_strsame(const char* dst, const char* src)
{
return dst && src ? _stricmp(dst, src) == 0 : false;
}
const char* CPathName::Path() const
{
char drive[_MAX_DRIVE], dir[_MAX_DIR];
_splitpath_s(_name, drive, sizeof(drive), dir, sizeof(dir), NULL, 0, NULL, 0);
gt_strcpy(__tmp, drive);
gt_strcat(__tmp, dir);
return __tmp;
}
const char* CPathName::FullName() const
{
char name[_MAX_FNAME], ext[_MAX_EXT];
_splitpath_s(c_str(), NULL, 0, NULL, 0, name, sizeof(name), ext, sizeof(ext));
gt_strcpy(__tmp, name);
gt_strcat(__tmp, ext);
return __tmp;
}
const char* CPathName::Name() const
{
_splitpath_s(c_str(), NULL, 0, NULL, 0, __tmp, sizeof(__tmp), NULL, 0);
return __tmp;
}
const char* CPathName::Ext() const
{
_splitpath_s(c_str(), NULL, 0, NULL, 0, NULL, 0, __tmp, sizeof(__tmp));
return __tmp;
}
CPathName& CPathName::Set(const char* p)
{
memset(_name, 0, sizeof(_name));
if (p && *p == '"')
{
gt_strcpy(_name, p+1);
_name[strlen(_name)-1] = '\0';
}
else
gt_strcpy(_name, p);
return *this;
}
CPathName& CPathName::Set(const char* p, const char* n, const char* e)
{
memset(_name, 0, sizeof(_name));
_makepath_s(_name, sizeof(_name), NULL, p, n, e);
return *this;
}
CPathName& CPathName::SetPath(const char* p)
{
char name[_MAX_FNAME], ext[_MAX_EXT];
_splitpath_s(c_str(), NULL, NULL, NULL, NULL, name, sizeof(name), ext, sizeof(ext));
_makepath_s(_name, sizeof(_name), NULL, p, name, ext);
return *this;
}
CPathName& CPathName::SetName(const char* n)
{
char drive[_MAX_DRIVE], dir[_MAX_DIR], ext[_MAX_EXT], path[_MAX_PATH];
_splitpath_s(c_str(), drive, sizeof(drive), dir, sizeof(dir), NULL, 0, ext, sizeof(ext));
_makepath_s(path, sizeof(path), drive, dir, n, ext);
return operator=(path);
}
CPathName& CPathName::SetExt(const char* e)
{
char drive[_MAX_DRIVE], dir[_MAX_DIR], name[_MAX_FNAME], ext[_MAX_EXT];
_splitpath_s(c_str(), drive, sizeof(drive), dir, sizeof(dir), name, sizeof(name), ext, sizeof(ext));
_makepath_s(_name, sizeof(_name), drive, dir, name, e);
return *this;
}
bool CPathName::IsFile() const
{
if (empty())
return false;
DWORD dwAttrib = ::GetFileAttributesA(c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
bool CPathName::IsDirectory() const
{
if (empty())
return false;
DWORD dwAttrib = ::GetFileAttributesA(c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
size_t CPathName::Scan(CPathList* files) const
{
WIN32_FIND_DATAA ffd = { 0 };
PVOID pOldValue = NULL;
::Wow64DisableWow64FsRedirection(&pOldValue);
size_t nCount = 0;
CPathName tmp = c_str();
if (tmp.IsDirectory())
tmp.Set(c_str(), "*", "*");
HANDLE hFind = ::FindFirstFileA(tmp, &ffd);
while (hFind != INVALID_HANDLE_VALUE)
{
if (files)
{
tmp.Set(Path(), ffd.cFileName, NULL);
files->push_back(tmp);
}
nCount++;
if (!::FindNextFileA(hFind, &ffd))
{
::FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
}
}
::Wow64RevertWow64FsRedirection(pOldValue);
return nCount;
}
bool CPathName::Copy(const CPathName& dst) const
{
return ::CopyFileA(c_str(), dst.c_str(), FALSE) != 0;
}
bool CPathName::Move(const CPathName& dst) const
{
if (dst.IsFile())
dst.Remove();
return ::MoveFileA(c_str(), dst.c_str()) != 0;
}
bool CPathName::Remove() const
{
return ::DeleteFileA(c_str()) != 0;
}
///////////////////////////////////////////////////////////
// CPathList
///////////////////////////////////////////////////////////
size_t CPathList::push_back(const char* p)
{
CPathName& pn = operator[](size_t(-1));
pn = p;
return _items-1;
}
size_t CPathList::push_back(const CPathName& p)
{
CPathName& pn = operator[](size_t(-1));
pn = p;
return _items-1;
}
const CPathName& CPathList::operator[](size_t i) const
{
assert(i < _items);
return _file[i];
}
CPathName& CPathList::operator[](size_t i)
{
if (i >= _items)
{
if (_items+1 >= _max)
{
const size_t s = _max ? _max*2 : 128;
CPathName* n = new CPathName[s];
for (size_t j = 0; j < _items; j++)
n[j].Set(_file[j]);
delete [] _file;
_file = n;
_max = s;
}
i = _items++;
}
return _file[i];
}
CPathList::~CPathList()
{
if (_file)
delete [] _file;
}

View File

@ -0,0 +1,78 @@
#pragma once
#ifndef __PATHNAME_H__
#define __PATHNAME_H__
///////////////////////////////////////////////////////////
// CPathName
///////////////////////////////////////////////////////////
typedef char gt_string[264];
errno_t gt_strcpy (_Out_z_cap_(264) gt_string dst, _In_z_ const char* src);
errno_t gt_strcat (_Out_z_cap_(264) gt_string dst, _In_z_ const char* src);
errno_t gt_chrcat (_Out_z_cap_(264) gt_string dst, _In_z_ const char src);
bool gt_strsame(_In_z_ const char* dst, _In_z_ const char* src);
class CPathList;
class CPathName
{
gt_string _name;
protected:
size_t Scan(CPathList* list) const;
public:
bool empty() const { return *_name <= ' '; }
const char* Path() const;
const char* FullName() const;
const char* Name() const;
const char* Ext() const;
CPathName& Set(const char* p);
CPathName& Set(const char* p, const char* n, const char* e);
CPathName& SetPath(const char* p);
CPathName& SetName(const char* n);
CPathName& SetExt(const char* e);
const char* c_str() const { return _name; }
operator const char*() const { return c_str(); }
bool operator==(const char* str) const { return gt_strsame(_name, str); }
CPathName& operator=(const char* str) { return Set(str); }
CPathName& operator=(const CPathName& p) { return Set(p.c_str()); }
bool IsFile() const;
bool IsDirectory() const;
size_t List(CPathList& files) const { return Scan(&files); }
size_t Count() const { return Scan(NULL); }
bool Copy(const CPathName& dst) const;
bool Move(const CPathName& dst) const;
bool Remove() const;
CPathName() { memset(_name, 0, sizeof(_name)); }
CPathName(const CPathName& n) { Set(n.c_str()); }
CPathName(const char* pathname) { Set(pathname); }
};
class CPathList
{
size_t _items, _max;
CPathName* _file;
public:
size_t size() const { return _items; }
size_t push_back(const char* p);
size_t push_back(const CPathName& p);
const CPathName& operator[](size_t i) const;
CPathName& operator[](size_t i);
CPathList() : _items(0), _max(0), _file(NULL) {}
~CPathList();
};
char* wstring2string(const wchar_t* str);
wchar_t* string2wstring(const char* str);
#endif

View File

@ -0,0 +1,110 @@
/****************************** Module Header ******************************\
* Module Name: CppWindowsService.cpp
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* The file defines the entry point of the application. According to the
* arguments in the command line, the function installs or uninstalls or
* starts the service by calling into different routines.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma region Includes
#include "SSAservice.h"
#include "ServiceInstaller.h"
#include <string>
#pragma endregion
//
// Settings of the service
//
// Internal name of the service
#define SERVICE_NAME TEXT("SSAservice")
// Displayed name of the service
#define SERVICE_DISPLAY_NAME TEXT("SSA Sirio Software Autentication")
// Service start options.
#define SERVICE_START_TYPE SERVICE_AUTO_START
// List of service dependencies - "dep1\0dep2\0\0"
#define SERVICE_DEPENDENCIES TEXT("")
// The name of the account under which the service should run
#define SERVICE_ACCOUNT TEXT("NT AUTHORITY\\LocalService")
// The password to the service account name
#define SERVICE_PASSWORD NULL
//
// FUNCTION: wmain(int, wchar_t *[])
//
// PURPOSE: entrypoint for the application.
//
// PARAMETERS:
// argc - number of command line arguments
// argv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// wmain() either performs the command line task, or run the service.
//
int wmain(int argc, wchar_t *argv[])
{
if ((argc > 1) && ((*argv[1] == L'-' || (*argv[1] == L'/'))))
{
if (_wcsicmp(L"install", argv[1] + 1) == 0)
{
InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_WIN32_OWN_PROCESS,
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
);
}
else if (_wcsicmp(L"remove", argv[1] + 1) == 0)
{
UninstallService(SERVICE_NAME);
}
else if (_wcsicmp(L"start", argv[1] + 1) == 0)
{
StartService(SERVICE_NAME);
}
else if (_wcsicmp(L"stop", argv[1] + 1) == 0)
{
StopService(SERVICE_NAME);
}
else if (_wcsicmp(L"restart", argv[1] + 1) == 0)
{
StopService(SERVICE_NAME);
::Sleep(1000);
StartService(SERVICE_NAME);
}
}
else
{
CSSAservice service(SERVICE_NAME);
if (!CServiceBase::Run(service))
{
wprintf(L"Parameters: -install -start -stop -restart -remove\n");
wprintf(L"Running as standard process from command line\n");
service.ServiceLoop();
}
}
return 0;
}

View File

@ -0,0 +1,249 @@
#pragma region Includes
#include "SSAservice.h"
#include "ThreadPool.h"
#include "PathName.h"
#include <string>
#include <psapi.h>
#pragma comment(lib, "Psapi.lib")
#pragma endregion
///////////////////////////////////////////////////////////
// CSSAservice
///////////////////////////////////////////////////////////
BOOL CSSAservice::FindAgent(HANDLE& hFound, DWORD& pid) const
{
DWORD* aProcesses = NULL;
DWORD nItems = 0, nFound = 0, i = 0;
hFound = 0;
pid = 0;
for (nItems = 256; ; nItems *= 2)
{
DWORD cbNeeded = 0;
free(aProcesses);
aProcesses = (DWORD*)calloc(nItems, sizeof(DWORD));
if (!EnumProcesses(aProcesses, nItems*sizeof(DWORD), &cbNeeded))
{
free(aProcesses);
return FALSE;
}
nFound = cbNeeded / sizeof(DWORD);
if (nFound < nItems)
break;
}
for (i = 0; i < nFound && hFound == NULL; i++) if (aProcesses[i])
{
HANDLE hProcess = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i] );
if (hProcess != NULL)
{
HMODULE hMod;
DWORD cbNeeded;
if (::EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
TCHAR szProcessName[MAX_PATH] = { 0 };
::GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) );
if (wcsstr(szProcessName, _agent) != NULL)
{
hFound = ::OpenProcess( SYNCHRONIZE, FALSE, aProcesses[i] ); // Waitable process handle
pid = aProcesses[i];
}
}
// Release the handle to the process.
CloseHandle( hProcess );
}
}
free(aProcesses);
return hFound != NULL;
}
BOOL CSSAservice::FindOrCreateAgent(HANDLE& hProcess, DWORD& pid) const
{
if (!FindAgent(hProcess, pid))
{
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si); // si.wShowWindow = SW_HIDE;
std::wstring str;
str = L"Creating instance of "; str += _agent;
WriteEventLogEntry(str.c_str());
if (CreateProcess(_agent,
NULL, // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
FALSE, // no Handle inheritance
CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS, // creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si,
&pi))
{
hProcess = pi.hProcess;
pid = pi.dwProcessId;
}
else
WriteErrorLogEntry(TEXT("CreateProcess"));
}
else
{
std::wstring str;
str = L"Attaching to instance of "; str += _agent;
WriteEventLogEntry(str.c_str());
}
return hProcess != 0;
}
void CSSAservice::CheckDirectory() const
{
char full[_MAX_PATH] = {0}; ::GetModuleFileNameA(NULL, full, sizeof(full));
CPathName pn = full;
::SetCurrentDirectoryA(pn.Path());
}
CSSAservice::CSSAservice(LPCTSTR pszServiceName,
BOOL fCanStop, BOOL fCanShutdown, BOOL fCanPauseContinue)
: CServiceBase(pszServiceName, fCanStop, fCanShutdown, fCanPauseContinue), _agent(NULL)
{
m_fStopping = FALSE;
// Create a manual-reset event that is not signaled at first to indicate
// the stopped signal of the service.
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hStoppedEvent == NULL)
throw GetLastError();
}
CSSAservice::~CSSAservice(void)
{
if (m_hStoppedEvent)
{
CloseHandle(m_hStoppedEvent);
m_hStoppedEvent = NULL;
}
}
//
// FUNCTION: CSSAservice::OnStart(DWORD, LPWSTR *)
//
// PURPOSE: The function is executed when a Start command is sent to the
// service by the SCM or when the operating system starts (for a service
// that starts automatically). It specifies actions to take when the
// service starts. In this code sample, OnStart logs a service-start
// message to the Application log, and queues the main service function for
// execution in a thread pool worker thread.
//
// PARAMETERS:
// * dwArgc - number of command line arguments
// * lpszArgv - array of command line arguments
//
// NOTE: A service application is designed to be long running. Therefore,
// it usually polls or monitors something in the system. The monitoring is
// set up in the OnStart method. However, OnStart does not actually do the
// monitoring. The OnStart method must return to the operating system after
// the service's operation has begun. It must not loop forever or block. To
// set up a simple monitoring mechanism, one general solution is to create
// a timer in OnStart. The timer would then raise events in your code
// periodically, at which time your service could do its monitoring. The
// other solution is to spawn a new thread to perform the main service
// functions, which is demonstrated in this code sample.
//
void CSSAservice::OnStart(DWORD dwArgc, LPWSTR *lpszArgv)
{
// Log a service start message to the Application log.
WriteEventLogEntry(TEXT("SSAservice Starting"));
// Queue the main service function for execution in a worker thread.
CThreadPool::QueueUserWorkItem(&CSSAservice::ServiceLoop, this);
}
//
// FUNCTION: CSSAservice::ServiceLoop(void)
//
// PURPOSE: The method performs the main function of the service. It runs
// on a thread pool worker thread.
//
void CSSAservice::ServiceLoop(void)
{
const int nSeconds = 5;
CheckDirectory();
WIN32_FIND_DATA fd = { 0 };
HANDLE hf = ::FindFirstFile(TEXT("*.ssa"), &fd);
if (hf)
{
_agent = TEXT("SSAagent.exe");
::FindClose(hf);
}
else
_agent = TEXT("Authoriz.exe");
HANDLE hProcess = 0;
DWORD pid = 0;
FindOrCreateAgent(hProcess, pid);
// Periodically check if the service is stopping.
while (hProcess && !m_fStopping)
{
DWORD ret = ::WaitForSingleObject(hProcess, nSeconds * 1000);
if (ret != WAIT_TIMEOUT)
{
WriteEventLogEntry(TEXT("Unexpected agent termination"), EVENTLOG_WARNING_TYPE);
::CloseHandle(hProcess);
FindOrCreateAgent(hProcess, pid);
}
}
if (hProcess)
{
::CloseHandle(hProcess);
HANDLE hAgent = ::OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hAgent)
{
if (::TerminateProcess(hAgent, 0))
_agent = NULL;
else
WriteErrorLogEntry(TEXT("TerminateProcess"));
::CloseHandle(hAgent);
}
else
WriteErrorLogEntry(TEXT("OpenProcess(PROCESS_TERMINATE)"));
}
// Signal the stopped event.
SetEvent(m_hStoppedEvent);
}
//
// FUNCTION: CSSAservice::OnStop(void)
//
// PURPOSE: The function is executed when a Stop command is sent to the
// service by SCM. It specifies actions to take when a service stops
// running. In this code sample, OnStop logs a service-stop message to the
// Application log, and waits for the finish of the main service function.
//
// COMMENTS:
// Be sure to periodically call ReportServiceStatus() with
// SERVICE_STOP_PENDING if the procedure is going to take long time.
//
void CSSAservice::OnStop()
{
// Log a service stop message to the Application log.
WriteEventLogEntry(L"SSAservice Stopping");
// Indicate that the service is stopping and wait for the finish of the
// main service function (ServiceWorkerThread).
m_fStopping = TRUE;
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
throw GetLastError();
}

View File

@ -0,0 +1,47 @@
/****************************** Module Header ******************************\
* Module Name: SampleService.h
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* Provides a sample service class that derives from the service base class -
* CServiceBase. The sample service logs the service start and stop
* information to the Application event log, and shows how to run the main
* function of the service in a thread pool worker thread.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma once
#include "ServiceBase.h"
class CSSAservice : public CServiceBase
{
LPCTSTR _agent;
public:
CSSAservice(LPCTSTR pszServiceName,
BOOL fCanStop = TRUE,
BOOL fCanShutdown = TRUE,
BOOL fCanPauseContinue = FALSE);
void ServiceLoop(void);
virtual ~CSSAservice();
protected:
virtual void OnStart(DWORD dwArgc, PWSTR *pszArgv);
virtual void OnStop();
BOOL FindAgent(HANDLE& hProcess, DWORD& pid) const;
BOOL FindOrCreateAgent(HANDLE& hProcess, DWORD& pid) const;
void CheckDirectory() const;
private:
BOOL m_fStopping;
HANDLE m_hStoppedEvent;
};

View File

@ -0,0 +1,560 @@
/****************************** Module Header ******************************\
* Module Name: ServiceBase.cpp
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* Provides a base class for a service that will exist as part of a service
* application. CServiceBase must be derived from when creating a new service
* class.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma region Includes
#include "ServiceBase.h"
#include <assert.h>
#include <strsafe.h>
#pragma endregion
#pragma region Static Members
// Initialize the singleton service instance.
CServiceBase *CServiceBase::s_service = NULL;
//
// FUNCTION: CServiceBase::Run(CServiceBase &)
//
// PURPOSE: Register the executable for a service with the Service Control
// Manager (SCM). After you call Run(ServiceBase), the SCM issues a Start
// command, which results in a call to the OnStart method in the service.
// This method blocks until the service has stopped.
//
// PARAMETERS:
// * service - the reference to a CServiceBase object. It will become the
// singleton service instance of this service application.
//
// RETURN VALUE: If the function succeeds, the return value is TRUE. If the
// function fails, the return value is FALSE. To get extended error
// information, call GetLastError.
//
BOOL CServiceBase::Run(CServiceBase &service)
{
s_service = &service;
SERVICE_TABLE_ENTRY serviceTable[] =
{
{ service.m_name, ServiceMain },
{ NULL, NULL }
};
// Connects the main thread of a service process to the service control
// manager, which causes the thread to be the service control dispatcher
// thread for the calling process. This call returns when the service has
// stopped. The process should simply terminate when the call returns.
return StartServiceCtrlDispatcher(serviceTable);
}
//
// FUNCTION: CServiceBase::ServiceMain(DWORD, PWSTR *)
//
// PURPOSE: Entry point for the service. It registers the handler function
// for the service and starts the service.
//
// PARAMETERS:
// * dwArgc - number of command line arguments
// * lpszArgv - array of command line arguments
//
void WINAPI CServiceBase::ServiceMain(DWORD dwArgc, PWSTR *pszArgv)
{
assert(s_service != NULL);
// Register the handler function for the service
s_service->m_statusHandle = RegisterServiceCtrlHandler(
s_service->m_name, ServiceCtrlHandler);
if (s_service->m_statusHandle == NULL)
{
throw GetLastError();
}
// Start the service.
s_service->Start(dwArgc, pszArgv);
}
//
// FUNCTION: CServiceBase::ServiceCtrlHandler(DWORD)
//
// PURPOSE: The function is called by the SCM whenever a control code is
// sent to the service.
//
// PARAMETERS:
// * dwCtrlCode - the control code. This parameter can be one of the
// following values:
//
// SERVICE_CONTROL_CONTINUE
// SERVICE_CONTROL_INTERROGATE
// SERVICE_CONTROL_NETBINDADD
// SERVICE_CONTROL_NETBINDDISABLE
// SERVICE_CONTROL_NETBINDREMOVE
// SERVICE_CONTROL_PARAMCHANGE
// SERVICE_CONTROL_PAUSE
// SERVICE_CONTROL_SHUTDOWN
// SERVICE_CONTROL_STOP
//
// This parameter can also be a user-defined control code ranges from 128
// to 255.
//
void WINAPI CServiceBase::ServiceCtrlHandler(DWORD dwCtrl)
{
switch (dwCtrl)
{
case SERVICE_CONTROL_STOP: s_service->Stop(); break;
case SERVICE_CONTROL_PAUSE: s_service->Pause(); break;
case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break;
case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break;
case SERVICE_CONTROL_INTERROGATE: break;
default: break;
}
}
#pragma endregion
#pragma region Service Constructor and Destructor
//
// FUNCTION: CServiceBase::CServiceBase(PWSTR, BOOL, BOOL, BOOL)
//
// PURPOSE: The constructor of CServiceBase. It initializes a new instance
// of the CServiceBase class. The optional parameters (fCanStop,
/// fCanShutdown and fCanPauseContinue) allow you to specify whether the
// service can be stopped, paused and continued, or be notified when system
// shutdown occurs.
//
// PARAMETERS:
// * pszServiceName - the name of the service
// * fCanStop - the service can be stopped
// * fCanShutdown - the service is notified when system shutdown occurs
// * fCanPauseContinue - the service can be paused and continued
//
CServiceBase::CServiceBase(LPCTSTR pszServiceName,
BOOL fCanStop,
BOOL fCanShutdown,
BOOL fCanPauseContinue)
{
// Service name must be a valid string and cannot be NULL.
m_name = (pszServiceName == NULL) ? L"" : pszServiceName;
m_statusHandle = NULL;
// The service runs in its own process.
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
// The service is starting.
m_status.dwCurrentState = SERVICE_START_PENDING;
// The accepted commands of the service.
DWORD dwControlsAccepted = 0;
if (fCanStop)
dwControlsAccepted |= SERVICE_ACCEPT_STOP;
if (fCanShutdown)
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
if (fCanPauseContinue)
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
m_status.dwControlsAccepted = dwControlsAccepted;
m_status.dwWin32ExitCode = NO_ERROR;
m_status.dwServiceSpecificExitCode = 0;
m_status.dwCheckPoint = 0;
m_status.dwWaitHint = 0;
}
//
// FUNCTION: CServiceBase::~CServiceBase()
//
// PURPOSE: The virtual destructor of CServiceBase.
//
CServiceBase::~CServiceBase(void)
{
}
#pragma endregion
#pragma region Service Start, Stop, Pause, Continue, and Shutdown
//
// FUNCTION: CServiceBase::Start(DWORD, PWSTR *)
//
// PURPOSE: The function starts the service. It calls the OnStart virtual
// function in which you can specify the actions to take when the service
// starts. If an error occurs during the startup, the error will be logged
// in the Application event log, and the service will be stopped.
//
// PARAMETERS:
// * dwArgc - number of command line arguments
// * lpszArgv - array of command line arguments
//
void CServiceBase::Start(DWORD dwArgc, PWSTR *pszArgv)
{
try
{
// Tell SCM that the service is starting.
SetServiceStatus(SERVICE_START_PENDING);
// Perform service-specific initialization.
OnStart(dwArgc, pszArgv);
// Tell SCM that the service is started.
SetServiceStatus(SERVICE_RUNNING);
}
catch (DWORD dwError)
{
// Log the error.
WriteErrorLogEntry(L"Service Start", dwError);
// Set the service status to be stopped.
SetServiceStatus(SERVICE_STOPPED, dwError);
}
catch (...)
{
// Log the error.
WriteEventLogEntry(L"Service failed to start.", EVENTLOG_ERROR_TYPE);
// Set the service status to be stopped.
SetServiceStatus(SERVICE_STOPPED);
}
}
//
// FUNCTION: CServiceBase::OnStart(DWORD, PWSTR *)
//
// PURPOSE: When implemented in a derived class, executes when a Start
// command is sent to the service by the SCM or when the operating system
// starts (for a service that starts automatically). Specifies actions to
// take when the service starts. Be sure to periodically call
// CServiceBase::SetServiceStatus() with SERVICE_START_PENDING if the
// procedure is going to take long time. You may also consider spawning a
// new thread in OnStart to perform time-consuming initialization tasks.
//
// PARAMETERS:
// * dwArgc - number of command line arguments
// * lpszArgv - array of command line arguments
//
void CServiceBase::OnStart(DWORD dwArgc, PWSTR *pszArgv)
{
}
//
// FUNCTION: CServiceBase::Stop()
//
// PURPOSE: The function stops the service. It calls the OnStop virtual
// function in which you can specify the actions to take when the service
// stops. If an error occurs, the error will be logged in the Application
// event log, and the service will be restored to the original state.
//
void CServiceBase::Stop()
{
DWORD dwOriginalState = m_status.dwCurrentState;
try
{
// Tell SCM that the service is stopping.
SetServiceStatus(SERVICE_STOP_PENDING);
// Perform service-specific stop operations.
OnStop();
// Tell SCM that the service is stopped.
SetServiceStatus(SERVICE_STOPPED);
}
catch (DWORD dwError)
{
// Log the error.
WriteErrorLogEntry(L"Service Stop", dwError);
// Set the orginal service status.
SetServiceStatus(dwOriginalState);
}
catch (...)
{
// Log the error.
WriteEventLogEntry(L"Service failed to stop.", EVENTLOG_ERROR_TYPE);
// Set the orginal service status.
SetServiceStatus(dwOriginalState);
}
}
//
// FUNCTION: CServiceBase::OnStop()
//
// PURPOSE: When implemented in a derived class, executes when a Stop
// command is sent to the service by the SCM. Specifies actions to take
// when a service stops running. Be sure to periodically call
// CServiceBase::SetServiceStatus() with SERVICE_STOP_PENDING if the
// procedure is going to take long time.
//
void CServiceBase::OnStop()
{
}
//
// FUNCTION: CServiceBase::Pause()
//
// PURPOSE: The function pauses the service if the service supports pause
// and continue. It calls the OnPause virtual function in which you can
// specify the actions to take when the service pauses. If an error occurs,
// the error will be logged in the Application event log, and the service
// will become running.
//
void CServiceBase::Pause()
{
try
{
// Tell SCM that the service is pausing.
SetServiceStatus(SERVICE_PAUSE_PENDING);
// Perform service-specific pause operations.
OnPause();
// Tell SCM that the service is paused.
SetServiceStatus(SERVICE_PAUSED);
}
catch (DWORD dwError)
{
// Log the error.
WriteErrorLogEntry(L"Service Pause", dwError);
// Tell SCM that the service is still running.
SetServiceStatus(SERVICE_RUNNING);
}
catch (...)
{
// Log the error.
WriteEventLogEntry(L"Service failed to pause.", EVENTLOG_ERROR_TYPE);
// Tell SCM that the service is still running.
SetServiceStatus(SERVICE_RUNNING);
}
}
//
// FUNCTION: CServiceBase::OnPause()
//
// PURPOSE: When implemented in a derived class, executes when a Pause
// command is sent to the service by the SCM. Specifies actions to take
// when a service pauses.
//
void CServiceBase::OnPause()
{
}
//
// FUNCTION: CServiceBase::Continue()
//
// PURPOSE: The function resumes normal functioning after being paused if
// the service supports pause and continue. It calls the OnContinue virtual
// function in which you can specify the actions to take when the service
// continues. If an error occurs, the error will be logged in the
// Application event log, and the service will still be paused.
//
void CServiceBase::Continue()
{
try
{
// Tell SCM that the service is resuming.
SetServiceStatus(SERVICE_CONTINUE_PENDING);
// Perform service-specific continue operations.
OnContinue();
// Tell SCM that the service is running.
SetServiceStatus(SERVICE_RUNNING);
}
catch (DWORD dwError)
{
// Log the error.
WriteErrorLogEntry(L"Service Continue", dwError);
// Tell SCM that the service is still paused.
SetServiceStatus(SERVICE_PAUSED);
}
catch (...)
{
// Log the error.
WriteEventLogEntry(L"Service failed to resume.", EVENTLOG_ERROR_TYPE);
// Tell SCM that the service is still paused.
SetServiceStatus(SERVICE_PAUSED);
}
}
//
// FUNCTION: CServiceBase::OnContinue()
//
// PURPOSE: When implemented in a derived class, OnContinue runs when a
// Continue command is sent to the service by the SCM. Specifies actions to
// take when a service resumes normal functioning after being paused.
//
void CServiceBase::OnContinue()
{
}
//
// FUNCTION: CServiceBase::Shutdown()
//
// PURPOSE: The function executes when the system is shutting down. It
// calls the OnShutdown virtual function in which you can specify what
// should occur immediately prior to the system shutting down. If an error
// occurs, the error will be logged in the Application event log.
//
void CServiceBase::Shutdown()
{
try
{
// Perform service-specific shutdown operations.
OnShutdown();
// Tell SCM that the service is stopped.
SetServiceStatus(SERVICE_STOPPED);
}
catch (DWORD dwError)
{
// Log the error.
WriteErrorLogEntry(L"Service Shutdown", dwError);
}
catch (...)
{
// Log the error.
WriteEventLogEntry(L"Service failed to shut down.", EVENTLOG_ERROR_TYPE);
}
}
//
// FUNCTION: CServiceBase::OnShutdown()
//
// PURPOSE: When implemented in a derived class, executes when the system
// is shutting down. Specifies what should occur immediately prior to the
// system shutting down.
//
void CServiceBase::OnShutdown()
{
}
#pragma endregion
#pragma region Helper Functions
//
// FUNCTION: CServiceBase::SetServiceStatus(DWORD, DWORD, DWORD)
//
// PURPOSE: The function sets the service status and reports the status to
// the SCM.
//
// PARAMETERS:
// * dwCurrentState - the state of the service
// * dwWin32ExitCode - error code to report
// * dwWaitHint - estimated time for pending operation, in milliseconds
//
void CServiceBase::SetServiceStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
// Fill in the SERVICE_STATUS structure of the service.
m_status.dwCurrentState = dwCurrentState;
m_status.dwWin32ExitCode = dwWin32ExitCode;
m_status.dwWaitHint = dwWaitHint;
m_status.dwCheckPoint =
((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED)) ?
0 : dwCheckPoint++;
// Report the status of the service to the SCM.
::SetServiceStatus(m_statusHandle, &m_status);
}
//
// FUNCTION: CServiceBase::WriteEventLogEntry(PWSTR, WORD)
//
// PURPOSE: Log a message to the Application event log.
//
// PARAMETERS:
// * pszMessage - string message to be logged.
// * wType - the type of event to be logged. The parameter can be one of
// the following values.
//
// EVENTLOG_SUCCESS
// EVENTLOG_AUDIT_FAILURE
// EVENTLOG_AUDIT_SUCCESS
// EVENTLOG_ERROR_TYPE
// EVENTLOG_INFORMATION_TYPE
// EVENTLOG_WARNING_TYPE
//
void CServiceBase::WriteEventLogEntry(LPCTSTR pszMessage, WORD wType, DWORD id) const
{
HANDLE hEventSource = ::RegisterEventSource(NULL, m_name);
if (hEventSource)
{
LPCTSTR lpszStrings[2] = { NULL, NULL };
lpszStrings[0] = m_name;
lpszStrings[1] = pszMessage;
::ReportEvent(hEventSource, // Event log handle
wType, // Event type
0, // Event category
id, // Event identifier
NULL, // No security identifier
2, // Size of lpszStrings array
0, // No binary data
lpszStrings, // Array of strings
NULL // No binary data
);
::DeregisterEventSource(hEventSource);
}
}
//
// FUNCTION: CServiceBase::WriteErrorLogEntry(PWSTR, DWORD)
//
// PURPOSE: Log an error message to the Application event log.
//
// PARAMETERS:
// * pszFunction - the function that gives the error
// * dwError - the error code
//
void CServiceBase::WriteErrorLogEntry(LPCTSTR pszFunction, DWORD dwError) const
{
wchar_t szMessage[260];
StringCchPrintf(szMessage, ARRAYSIZE(szMessage),
L"%s failed: error 0x%08lx", pszFunction, dwError);
WriteEventLogEntry(szMessage, EVENTLOG_ERROR_TYPE, dwError);
}
#pragma endregion

View File

@ -0,0 +1,126 @@
/****************************** Module Header ******************************\
* Module Name: ServiceBase.h
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* Provides a base class for a service that will exist as part of a service
* application. CServiceBase must be derived from when creating a new service
* class.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma once
#pragma region Includes
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <stdio.h>
#pragma endregion
class CServiceBase
{
public:
// Register the executable for a service with the Service Control Manager
// (SCM). After you call Run(ServiceBase), the SCM issues a Start command,
// which results in a call to the OnStart method in the service. This
// method blocks until the service has stopped.
static BOOL Run(CServiceBase &service);
// Service object constructor. The optional parameters (fCanStop,
// fCanShutdown and fCanPauseContinue) allow you to specify whether the
// service can be stopped, paused and continued, or be notified when
// system shutdown occurs.
CServiceBase(LPCTSTR pszServiceName,
BOOL fCanStop = TRUE,
BOOL fCanShutdown = TRUE,
BOOL fCanPauseContinue = FALSE);
// Service object destructor.
virtual ~CServiceBase(void);
// Stop the service.
void Stop();
protected:
// When implemented in a derived class, executes when a Start command is
// sent to the service by the SCM or when the operating system starts
// (for a service that starts automatically). Specifies actions to take
// when the service starts.
virtual void OnStart(DWORD dwArgc, PWSTR *pszArgv);
// When implemented in a derived class, executes when a Stop command is
// sent to the service by the SCM. Specifies actions to take when a
// service stops running.
virtual void OnStop();
// When implemented in a derived class, executes when a Pause command is
// sent to the service by the SCM. Specifies actions to take when a
// service pauses.
virtual void OnPause();
// When implemented in a derived class, OnContinue runs when a Continue
// command is sent to the service by the SCM. Specifies actions to take
// when a service resumes normal functioning after being paused.
virtual void OnContinue();
// When implemented in a derived class, executes when the system is
// shutting down. Specifies what should occur immediately prior to the
// system shutting down.
virtual void OnShutdown();
// Set the service status and report the status to the SCM.
void SetServiceStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode = NO_ERROR,
DWORD dwWaitHint = 0);
// Log a message to the Application event log.
void WriteEventLogEntry(LPCTSTR pszMessage, WORD wType = EVENTLOG_INFORMATION_TYPE, DWORD id = 0) const;
// Log an error message to the Application event log.
void WriteErrorLogEntry(LPCTSTR pszFunction, DWORD dwError = GetLastError()) const;
private:
// Entry point for the service. It registers the handler function for the
// service and starts the service.
static void WINAPI ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv);
// The function is called by the SCM whenever a control code is sent to
// the service.
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
// Start the service.
void Start(DWORD dwArgc, PWSTR *pszArgv);
// Pause the service.
void Pause();
// Resume the service after being paused.
void Continue();
// Execute when the system is shutting down.
void Shutdown();
// The singleton service instance.
static CServiceBase *s_service;
// The name of the service
PWSTR m_name;
// The status of the service
SERVICE_STATUS m_status;
// The service status handle
SERVICE_STATUS_HANDLE m_statusHandle;
};

View File

@ -0,0 +1,256 @@
/****************************** Module Header ******************************\
* Module Name: ServiceInstaller.cpp
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* The file implements functions that install and uninstall the service.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma region "Includes"
#include "ServiceBase.h"
#include "ServiceInstaller.h"
#pragma endregion
static bool LogError(const char* funcname)
{
fprintf(stderr, "%s failed with error 0x%08lx\n", funcname, GetLastError());
return false;
}
class SCManager
{
SC_HANDLE _handle;
public:
bool IsOk() const { return _handle != NULL; }
operator SC_HANDLE() const { return _handle; }
bool Start(LPCTSTR pszServiceName);
bool Stop(LPCTSTR pszServiceName);
bool Delete(LPCTSTR pszServiceName);
SCManager(DWORD mode)
{
_handle = ::OpenSCManager(NULL, NULL, mode);
if (_handle == NULL)
LogError("OpenSCManager");
}
~SCManager()
{
if (_handle != NULL)
CloseServiceHandle(_handle);
}
};
bool SCManager::Stop(LPCTSTR pszServiceName)
{
bool bDone = false;
if (IsOk())
{
// Open the service with delete, stop, and query status permissions
SC_HANDLE schService = ::OpenService(_handle, pszServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS);
if (schService == NULL)
{
LogError("OpenService");
return false;
}
// Try to stop the service
SERVICE_STATUS ssSvcStatus = {};
if (::ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus))
{
wprintf(L"Stopping %s.", pszServiceName);
while (::QueryServiceStatus(schService, &ssSvcStatus))
{
if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
wprintf(L".");
Sleep(1000);
}
else
break;
}
bDone = ssSvcStatus.dwCurrentState == SERVICE_STOPPED;
wprintf(L"\n");
}
::CloseServiceHandle(schService);
if (bDone)
wprintf(L"%s stopped.\n", pszServiceName);
else
wprintf(L"%s failed to stop.\n", pszServiceName);
}
return bDone;
}
bool SCManager::Start(LPCTSTR pszServiceName)
{
bool bDone = false;
if (IsOk())
{
SC_HANDLE schService = ::OpenService(_handle, pszServiceName, SERVICE_START);
if (schService)
{
bDone = ::StartService(schService, 0, NULL) != 0;
if (bDone)
wprintf(L"%s started.\n", pszServiceName);
else
LogError("StartService");
}
else
LogError("OpenService");
}
return bDone;
}
bool SCManager::Delete(LPCTSTR pszServiceName)
{
bool bDone = false;
if (IsOk())
{
// Open the service with delete, stop, and query status permissions
SC_HANDLE schService = ::OpenService(_handle, pszServiceName, DELETE);
if (schService)
{
// Now remove the service by calling DeleteService.
bDone = ::DeleteService(schService) != 0;
if (bDone)
wprintf(L"%s has been removed.\n", pszServiceName);
else
LogError("DeleteService");
// Centralized cleanup for all allocated resources.
if (schService)
{
CloseServiceHandle(schService);
schService = NULL;
}
}
else
LogError("OpenService");
}
return bDone;
}
//
// FUNCTION: InstallService
//
// PURPOSE: Install the current application as a service to the local
// service control manager database.
//
// PARAMETERS:
// * pszServiceName - the name of the service to be installed
// * pszDisplayName - the display name of the service
// * dwStartType - the service start option. This parameter can be one of
// the following values: SERVICE_AUTO_START, SERVICE_BOOT_START,
// SERVICE_DEMAND_START, SERVICE_DISABLED, SERVICE_SYSTEM_START.
// * pszDependencies - a pointer to a double null-terminated array of null-
// separated names of services or load ordering groups that the system
// must start before this service.
// * pszAccount - the name of the account under which the service runs.
// * pszPassword - the password to the account name.
//
// NOTE: If the function fails to install the service, it prints the error
// in the standard output stream for users to diagnose the problem.
//
bool InstallService(LPCTSTR pszServiceName,
LPCTSTR pszDisplayName,
DWORD dwServiceType,
DWORD dwStartType,
LPCTSTR pszDependencies,
LPCTSTR pszAccount,
LPCTSTR pszPassword)
{
TCHAR szPath[MAX_PATH];
if (::GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0)
return LogError("GetModuleFileName");
if (dwServiceType == 0)
dwServiceType = SERVICE_WIN32_OWN_PROCESS;
// Open the local default service control manager database
SCManager schSCManager(SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
if (schSCManager.IsOk())
{
// Install the service into SCM by calling CreateService
SC_HANDLE schService = ::CreateService(
schSCManager, // SCManager database
pszServiceName, // Name of service
pszDisplayName, // Name to display
SERVICE_QUERY_STATUS, // Desired access
dwServiceType, // Service type
dwStartType, // Service start type
SERVICE_ERROR_NORMAL, // Error control type
szPath, // Service's binary
NULL, // No load ordering group
NULL, // No tag identifier
pszDependencies, // Dependencies
pszAccount, // Service running account
pszPassword // Password of the account
);
if (schService != NULL)
{
wprintf(L"%s (%s) has been installed.\n", pszServiceName, pszDisplayName);
CloseServiceHandle(schService);
}
else
return LogError("CreateService");
}
return true;
}
//
// FUNCTION: UninstallService
//
// PURPOSE: Stop and remove the service from the local service control
// manager database.
//
// PARAMETERS:
// * pszServiceName - the name of the service to be removed.
//
// NOTE: If the function fails to uninstall the service, it prints the
// error in the standard output stream for users to diagnose the problem.
//
bool UninstallService(PWSTR pszServiceName)
{
bool done = false;
// Open the local default service control manager database
SCManager schSCManager(SC_MANAGER_CONNECT);
if (schSCManager.IsOk())
{
schSCManager.Stop(pszServiceName);
done = schSCManager.Delete(pszServiceName);
}
return done;
}
bool StartService(PWSTR pszServiceName)
{
bool done = false;
SCManager schSCManager(SC_MANAGER_CONNECT);
if (schSCManager.IsOk())
done = schSCManager.Start(pszServiceName);
return done;
}
bool StopService(PWSTR pszServiceName)
{
bool done = false;
SCManager schSCManager(SC_MANAGER_CONNECT);
if (schSCManager.IsOk())
done = schSCManager.Stop(pszServiceName);
return done;
}

View File

@ -0,0 +1,78 @@
/****************************** Module Header ******************************\
* Module Name: ServiceInstaller.h
* Project: CppWindowsService
* Copyright (c) Microsoft Corporation.
*
* The file declares functions that install and uninstall the service.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
#pragma once
//
// FUNCTION: InstallService
//
// PURPOSE: Install the current application as a service to the local
// service control manager database.
//
// PARAMETERS:
// * pszServiceName - the name of the service to be installed
// * pszDisplayName - the display name of the service
// * dwStartType - the service start option. This parameter can be one of
// the following values: SERVICE_AUTO_START, SERVICE_BOOT_START,
// SERVICE_DEMAND_START, SERVICE_DISABLED, SERVICE_SYSTEM_START.
// * pszDependencies - a pointer to a double null-terminated array of null-
// separated names of services or load ordering groups that the system
// must start before this service.
// * pszAccount - the name of the account under which the service runs.
// * pszPassword - the password to the account name.
//
// NOTE: If the function fails to install the service, it prints the error
// in the standard output stream for users to diagnose the problem.
//
bool InstallService(LPCTSTR pszServiceName,
LPCTSTR pszDisplayName,
DWORD dwServiceType,
DWORD dwStartType,
LPCTSTR pszDependencies,
LPCTSTR pszAccount,
LPCTSTR pszPassword);
//
// FUNCTION: UninstallService
//
// PURPOSE: Stop and remove the service from the local service control
// manager database.
//
// PARAMETERS:
// * pszServiceName - the name of the service to be removed.
//
// NOTE: If the function fails to uninstall the service, it prints the
// error in the standard output stream for users to diagnose the problem.
//
bool UninstallService(PWSTR pszServiceName);
//
// FUNCTION: StartStopService
//
// PURPOSE: Starts or Stops the service
//
// PARAMETERS:
// * pszServiceName - the name of the service to be started or stopped.
// bStart - TRUE to start or FALSE to stop
//
// NOTE: If the function fails to uninstall the service, it prints the
// error in the standard output stream for users to diagnose the problem.
//
bool StartService(PWSTR pszServiceName);
bool StopService(PWSTR pszServiceName);

View File

@ -0,0 +1,31 @@
#pragma once
#include <memory>
class CThreadPool
{
public:
template <typename T>
static void QueueUserWorkItem(void (T::*function)(void), T *object, ULONG flags = WT_EXECUTELONGFUNCTION)
{
typedef std::pair<void (T::*)(), T *> CallbackType;
std::auto_ptr<CallbackType> p(new CallbackType(function, object));
if (::QueueUserWorkItem(ThreadProc<T>, p.get(), flags))
p.release();
else
throw GetLastError();
}
private:
template <typename T>
static DWORD WINAPI ThreadProc(PVOID context)
{
typedef std::pair<void (T::*)(), T *> CallbackType;
std::auto_ptr<CallbackType> p(static_cast<CallbackType *>(context));
(p->second->*p->first)();
return 0;
}
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
set path=C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
del *.cer
makecert -n "CN=Guysoft Certificate Authority" -cy authority -a sha1 -sv "Guysoft.pvk" -r "Guysoft.cer"
makecert -n "CN=VisualGala.com" -ic "Guysoft.cer" -iv "Guysoft.pvk" -a sha1 -sky exchange -pe -sr localmachine -ss my "VisualGala.cer"

Binary file not shown.

View File

@ -0,0 +1,68 @@
#pragma once
#ifndef _ESIGNER_DLL
#define _ESIGNER_DLL
#define ESIGNER_USE_SHA1_DIGEST 0
#define ESIGNER_USE_SHA256_DIGEST 1
#define ESIGNER_NO_ERROR 0
#define ESIGNER_TOKEN_OPERATION_ERROR -1
#define ESIGNER_CERT_READ_FAILURE -2
#define ESIGNER_PKEY_READ_FAILURE -3
#define ESIGNER_PFX_PARSE_FAILURE -4
#define ESIGNER_CERT_RETRIEVE_TOKEN_FAILURE -5
#define ESIGNER_FILE_OPENING_ERROR -6
#define ESIGNER_TSA_URI_CONTACT_ERROR -7
#define ESIGNER_TSA_RESPONSE_ERROR -8
#define ESIGNER_TSA_RESPONSE_UNPARSABLE -9
#define ESIGNER_TOKEN_LOGIN_FAILED -10
#define ESIGNER_PKCS11_DLL_NOT_FOUND -11
#define ESIGNER_TOKEN_SLOT_NOT_FOUND -12
#define ESIGNER_OUTPUT_FILE_OPENING_ERROR -13
#define ESIGNER_OUTPUT_FILE_ALREADY_EXISTS_ERROR -14
#define ESIGNER_ERROR_TIMESTAMP_FILE -15
#define ESIGNER_TIMESTAMPING_FILE_OPENING_ERROR -16
#define ESIGNER_FILE_NOT_SIGNED -20
#define ESIGNER_FAKE_P7M -21
#define ESIGNER_SIGNATURE_INVALID -22
#define ESIGNER_CERTIFICATE_REVOKED -23
#define ESIGNER_SIGNED_BUT_TIME_STAMP_ERROR -25
#define ESIGNER_ROOT_CA_CERT_NOT_FOUND -30
#define ESIGNER_CRL_NOT_RETRIEVED -31
#define ESIGNER_CERTIFICATE_REVOKED_BUT_SIGNATURE_VALID -32
#define ESIGNER_CERTIFICATE_SELFSIGNED -33
#define ESIGNER_SIGNER_CERTIFICATE_EXPIRED -34
#define ESIGNER_SIGNER_CERTIFICATE_OUT_OF_TIME_VALIDITY -35
typedef int (PASCAL * ESignerSignProto) (
char *operation,
char *method,
char *inputFile,
char *outputFile,
char *timestampOutputFile,
char *extension,
char *certificateFile,
char *kprivFile,
char *pfxFile,
char *pkcs11Dll,
char *pin_passphrase,
char *directoryTokenCache,
char *indexCertificateOnToken,
char *tsaURI,
char *tsaUsername,
char *tsaPassword,
char *tsaPolicy,
char *tsaCoding,
char *rootCADir
);
typedef int (PASCAL * ESignerVerifyProto) (
char *operation,
char *inputFileName,
char *responseFileName,
char *rootCADir,
char *rootTSADir,
char *resultDescription
);
#endif

26
src/R_10_00/ab/ab0.cpp Executable file
View File

@ -0,0 +1,26 @@
#include <xvt.h>
#include <checks.h>
#include "ab0.h"
#define usage "Error - usage : %s -{0|1|2|3}"
int main(int argc,char** argv)
{
int n = (argc > 1) ? atoi(argv[1]+1) : -1;
switch (n)
{
case 0:
ab0100(argc,argv); break;
case 1:
ab0200(argc,argv); break;
case 2:
ab0300(argc,argv); break;
case 3:
ab0400(argc,argv); break;
default:
error_box(usage, argv[0]) ;
}
exit(0);
}

6
src/R_10_00/ab/ab0.h Executable file
View File

@ -0,0 +1,6 @@
extern int ab0100 (int argc, char* argv[]); //Tabella periodi di bilancio
extern int ab0200 (int argc, char* argv[]); //Piano dei conti analisi di bilancio
extern int ab0300 (int argc, char* argv[]); //Compatta il Piano dei Conti
extern int ab0400 (int argc, char* argv[]); //Riclassifica ed esporta i saldi

BIN
src/R_10_00/ab/ab01.bmp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

126
src/R_10_00/ab/ab0100.cpp Executable file
View File

@ -0,0 +1,126 @@
#include <modaut.h>
#include <tabapp.h>
#include <tabutil.h>
#include <utility.h>
#include "abtbpdb.h"
#include "abtbarb.h"
class Tabanabil_application : public Tab_application
{
private:
TMask* _msk;
TString _tabname;
public:
bool user_create();
const char * extra_modules() const { return format("%d",CGAUT); }
static bool giorno_handler(TMask_field& f, KEY k);
static bool mese_handler (TMask_field& f, KEY k);
static bool anni_handler (TMask_field& f, KEY k);
Tabanabil_application() {}
virtual ~Tabanabil_application() {}
};
HIDDEN inline Tabanabil_application& app() {return (Tabanabil_application&) main_app();}
bool Tabanabil_application::giorno_handler(TMask_field& f, KEY k)
{
if (k == K_TAB && f.mask().is_running())
{
const int giorno = atoi(f.get());
if (giorno > 31)
return f.warning_box(TR("Valore non valido per il giorno"));
const int mese = (f.dlg() == F_GIORNO_INI ? f.mask().get_int(F_MESE_INI) : f.mask().get_int(F_MESE_FINE));
if (mese == 2)
if (giorno > 29)
return f.warning_box(TR("Valore non valido per il giorno"));
if (mese == 11 || mese == 4 || mese == 6 || mese == 9)
if (giorno > 30)
return f.warning_box(TR("Valore non valido per il giorno"));
}
return TRUE;
}
bool Tabanabil_application::mese_handler(TMask_field& f, KEY k)
{
if (k == K_TAB && f.mask().is_running())
{
const int mese = atoi(f.get());
if (mese < 1 || mese > 12)
return f.warning_box(TR("Valore non valido per il mese"));
const int giorno = (f.dlg() == F_MESE_INI ? f.mask().get_int(F_GIORNO_INI) : f.mask().get_int(F_GIORNO_FINE));
if (mese == 2)
if (giorno > 28)
return f.warning_box(TR("Valore non valido per il giorno"));
if (mese == 11 || mese == 4 || mese == 6 || mese == 9)
if (giorno > 30)
return f.warning_box(TR("Valore non valido per il giorno"));
}
return TRUE;
}
bool Tabanabil_application::anni_handler(TMask_field& f, KEY k)
{
if (k == K_ENTER)
{
TMask & m=f.mask();
const TDate inizio(m.get_int(F_GIORNO_INI),m.get_int(F_MESE_INI),1993);
if (inizio.empty())
return TRUE;
const TDate fine(m.get_int(F_GIORNO_FINE),m.get_int(F_MESE_FINE),1993+m.get_int(F_NUM_ANNI));
if (fine.empty())
return TRUE;
if (fine==inizio)
return f.error_box(TR("Date uguali: specificare il numero di anni"));
if (fine<inizio)
return f.error_box(TR("Data finale inferiore alla iniziale: specificare il numero di anni"));
}
return TRUE;
}
bool Tabanabil_application::user_create()
{
Tab_application::user_create();
_msk = get_mask();
_tabname = get_tabname();
if (_tabname == "%PDB")
{
_msk->set_handler(F_GIORNO_INI, giorno_handler);
_msk->set_handler(F_MESE_INI, mese_handler);
_msk->set_handler(F_GIORNO_FINE, giorno_handler);
_msk->set_handler(F_MESE_FINE, mese_handler);
_msk->set_handler(F_NUM_ANNI, anni_handler);
}
if (_tabname == "%ARB")
set_search_field(F_CODTAB_ESE);
return TRUE;
}
int ab0100(int argc, char* argv[])
{
Tabanabil_application a;
a.run(argc,argv, TR("Tabelle"));
return 0;
}

232
src/R_10_00/ab/ab0200.cpp Executable file
View File

@ -0,0 +1,232 @@
#include <modaut.h>
#include <recarray.h>
#include <tabapp.h>
#include <utility.h>
#include "ab0200.h"
class TPconAb : public TRelation_application
{
TMask* _msk;
TRelation* _rel;
TString _codice;
int _indbil,_newindbil;
bool _isparametri;
static bool ContoSezBilOpp(TMask_field& f, KEY key);
static bool IndBil (TMask_field& f, KEY key);
void ScriviContoSezOpp (const TString& codice, const TString& val);
protected:
virtual bool user_create();
virtual bool user_destroy();
virtual int rewrite(const TMask& m);
virtual int write (const TMask& m);
virtual bool remove();
virtual TRelation* get_relation() const { return _rel; }
virtual TMask* get_mask(int mode) {return _msk;}
virtual bool changing_mask(int mode) {return FALSE;}
virtual void init_query_mode (TMask&);
virtual void init_modify_mode (TMask&);
virtual void init_insert_mode (TMask&);
public:
TPconAb() {} ;
};
// Handler che controlla, nel caso venga scelto un conto di sezione opposta gia' esistente,
// l'indicatore di bilancio del conto di sezione opposta e' "opposto" rispetto al conto
// "di partenza". Controlla inoltre, nel caso il conto di sezione opposta abbia a sua volta
// un conto di sezione opposta significativo, che quest'ultimo coincida con il conto "di partenza".
bool TPconAb::ContoSezBilOpp(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
const TString16 codice (f.get());
if (codice.not_empty())
{
const TRectype & pcon = cache().get(LF_ABPCON, codice);
const int indbilI = f.mask().get_int(F_INDBIL);
const int indbilII = pcon.get_int("INDBIL");
if (indbilI == 1 && indbilII != 2)
return f.warning_box(TR("L'indicatore di bilancio del conto di sezione opposta deve essere una passivita'"));
if (indbilI == 2 && indbilII != 1)
return f.warning_box(TR("L'indicatore di bilancio del conto di sezione opposta deve essere un'attivita'"));
if (indbilI == 3 && indbilII != 4)
return f.warning_box(TR("L'indicatore di bilancio del conto di sezione opposta deve essere un ricavo"));
if (indbilI == 4 && indbilII != 3)
return f.warning_box(TR("L'indicatore di bilancio del conto di sezione opposta deve essere un costo"));
const TString16 codopp(pcon.get("CODCONTR"));
if (codopp.not_empty() && (codopp != f.mask().get(F_CODICE)))
return f.warning_box(TR("Il conto di sezione opposta risulta diverso dal conto di sezione di partenza"));
}
}
return TRUE;
}
// Handler che abilita il campo "Conto di sezione opposta" se l'indicatore
// di bilancio e' compreso tra 1 e 4, e lo disabilita in tutti gli altri casi.
bool TPconAb::IndBil(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
int indbil = atoi(f.get());
if (indbil == 1 || indbil == 2 || indbil == 3 || indbil == 4)
f.mask().enable(F_CODCONTR);
else
f.mask().disable(F_CODCONTR);
}
return TRUE;
}
void TPconAb::init_query_mode(TMask&)
{
if (_isparametri)
{
_msk->set(F_CODCONTR, _codice);
_msk->set(F_INDBIL, _newindbil);
_msk->disable(F_CODCONTR);
_msk->disable(F_INDBIL);
}
}
void TPconAb::init_modify_mode(TMask&)
{
if (_isparametri)
{
_msk->set(F_CODCONTR, _codice);
_msk->set(F_INDBIL, _newindbil);
_msk->disable(F_CODCONTR);
_msk->disable(F_INDBIL);
}
}
void TPconAb::init_insert_mode(TMask&)
{
if (_isparametri)
{
_msk->set(F_CODCONTR, _codice);
_msk->set(F_INDBIL, _newindbil);
_msk->disable(F_CODCONTR);
_msk->disable(F_INDBIL);
}
}
void TPconAb::ScriviContoSezOpp(const TString& codice, const TString& val)
{
TLocalisamfile pcon(LF_ABPCON);
pcon.setkey(1);
pcon.zero();
pcon.put("CODCBL", codice);
if (pcon.read() == NOERR)
{
pcon.put("CODCONTR", val);
pcon.rewrite();
}
}
int TPconAb::rewrite(const TMask& m)
{
TString16 codopp = _rel->curr(LF_ABPCON).get("CODCONTR");
ScriviContoSezOpp(codopp,"");
m.autosave(*_rel);
codopp = m.get(F_CODCONTR);
TString16 val (m.get(F_CODICE));
ScriviContoSezOpp(codopp,val);
return _rel->rewrite();
}
int TPconAb::write(const TMask& m)
{
TString16 codopp (m.get(F_CODCONTR));
TString16 val (m.get(F_CODICE));
ScriviContoSezOpp(codopp,val);
m.autosave(*_rel);
return _rel->write();
}
bool TPconAb::remove()
{
TString16 codopp = _rel->curr(LF_ABPCON).get("CODCONTR");
ScriviContoSezOpp(codopp,"");
return TRelation_application::remove();
}
bool TPconAb::user_create()
{
open_files(LF_TAB, LF_TABCOM, LF_ABPCON, 0);
_rel = new TRelation (LF_ABPCON);
_msk = new TMask("ab0200a") ;
_msk->set_handler(F_CODCONTR, ContoSezBilOpp);
_msk->set_handler(F_INDBIL, IndBil);
_isparametri = FALSE;
if (argc() == 5 || argc() == 4) // solo si viene specificato codice e indbil, non importa se l'ultimo e' l'utente
{
// Originariamente dava un GPF, se non si controllava quanti parametri ci sono sulla riga di comando,
// inoltre non ha senso una linea cosi' fatta:
// ab0 -1 /uPRASSI <indbil>
// perche' cosi' prende come _codice l'utente. (Basta che sia diverso da /uPRASSI)
// Percio' l'analisi dei parametri viene cosi' cambiata: l'utente e' sempre l'ultimo parametro,
// quindi si avranno o 3 (2) o 5(4) parametri, di cui l'ultimo e' sempre l'utente (parametro 3 o 5)
// mentre i parametri 3 e 4 saranno il codice e indbil. E' percio' fondamentale controllare
// il numero dei parametri.
_codice = argv(2);
_indbil = atoi(argv(3));
if (_indbil == 1) _newindbil = 2;
if (_indbil == 2) _newindbil = 1;
if (_indbil == 3) _newindbil = 4;
if (_indbil == 4) _newindbil = 3;
_isparametri = TRUE;
}
set_search_field(F_CODICE);
return TRUE;
}
bool TPconAb::user_destroy()
{
delete _msk;
delete _rel;
return TRUE;
}
int ab0200(int argc, char* argv[])
{
TPconAb a;
a.run(argc, argv, TR("Piano dei Conti"));
return TRUE;
}

8
src/R_10_00/ab/ab0200.h Executable file
View File

@ -0,0 +1,8 @@
// campi maschera ab0200a.uml
#define F_CODICE 101
#define F_DESCRIZ 102
#define F_INDBIL 103
#define F_CODCONTR 104
#define F_DETTAGLIO 105
#define SOSPENDI 106

101
src/R_10_00/ab/ab0200a.uml Executable file
View File

@ -0,0 +1,101 @@
#include "ab0200.h"
TOOLBAR "topbar" 0 0 0 2
#include <relapbar.h>
ENDPAGE
PAGE "Piano dei Conti" 0 -1 0 19
GROUPBOX DLG_NULL 76 6
BEGIN
PROMPT 1 0 ""
FLAGS "R"
END
NUMBER F_CODICE 12
BEGIN
PROMPT 2 2 "Codice conto "
HELP "Codice della tabella Piano dei Conti"
FIELD LF_ABPCON->CODCBL
KEY 1
USE LF_ABPCON KEY 1
INPUT CODCBL F_CODICE
DISPLAY "Codice@12" CODCBL
DISPLAY "Descrizione@40" DESCRIZ
DISPLAY "I.B." INDBIL
DISPLAY "Codice opp.@12" CODCONTR
DISPLAY "Sospeso@2" SOSPESO
OUTPUT F_CODICE CODCBL
OUTPUT F_DESCRIZ DESCRIZ
CHECKTYPE REQUIRED
FLAGS "ZRU"
END
STRING F_DESCRIZ 80 40
BEGIN
PROMPT 2 4 "Descrizione "
FIELD LF_ABPCON->DESCRIZ
KEY 2
USE LF_ABPCON KEY 2
INPUT DESCRIZ F_DESCRIZ
DISPLAY "Descrizione@40" DESCRIZ
DISPLAY "Codice@12" CODCBL
DISPLAY "I.B." INDBIL
DISPLAY "Codice opp.@12" CODCONTR
DISPLAY "Sospeso@2" SOSPESO
COPY OUTPUT F_CODICE
HELP "Prima parte della descrizione"
WARNING "Manca la descrizione"
CHECKTYPE REQUIRED // Guy: perche' non cosi'?
END
LIST F_INDBIL 15
BEGIN
PROMPT 2 8 "Indicatore di bilancio "
FIELD LF_ABPCON->INDBIL
ITEM "1|Attivita'"
ITEM "2|Passivita'"
ITEM "3|Costi"
ITEM "4|Ricavi"
ITEM "5|Conti d'ordine"
ITEM "9|Varie"
END
NUMBER F_CODCONTR 12
BEGIN
PROMPT 2 10 "Conto di sez.bil.opposta "
HELP "Inserire il conto di sezione di bilancio opposta"
FIELD LF_ABPCON->CODCONTR
USE LF_ABPCON
INPUT CODCBL F_CODCONTR
DISPLAY "Codice@12" CODCBL
DISPLAY "Descrizione@40" DESCRIZ
DISPLAY "I.B." INDBIL
DISPLAY "Codice@12" CODCONTR
DISPLAY "Sospeso@2" SOSPESO
OUTPUT F_CODCONTR CODCBL
CHECKTYPE NORMAL
ADD RUN AB0 -1 #F_CODICE #F_INDBIL
FLAGS "ZRU"
END
//Questo campo è stato tolto
//LIST F_DETTAGLIO 15
//BEGIN
// PROMPT 2 14 "Dettaglio/Movimenti "
// FIELD LF_ABPCON->DETT
// ITEM " |Nessuno"
// ITEM "D|Dettaglio"
// ITEM "M|Movimenti"
//END
BOOLEAN SOSPENDI
BEGIN
PROMTP 2 16 " Conto sospeso"
FIELD LF_ABPCON->SOSPESO
END
ENDPAGE
ENDMASK

38
src/R_10_00/ab/ab0300.cpp Executable file
View File

@ -0,0 +1,38 @@
// Compatta Piano dei Conti Analisi di Bilancio
#include <applicat.h>
#include <isam.h>
#include "ab0.h"
class TComp_abpcon : public TSkeleton_application
{
public:
virtual bool create();
virtual void main_loop() {};
TComp_abpcon() {}
};
bool TComp_abpcon::create()
{
open_files(LF_TAB, LF_TABCOM, 0);
return TSkeleton_application::create();
}
int ab0300 (int argc, char* argv[])
{
TComp_abpcon main_app;
main_app.run(argc, argv, TR("Compatta"));
return TRUE;
}

951
src/R_10_00/ab/ab0400.cpp Executable file
View File

@ -0,0 +1,951 @@
#include <automask.h>
#include <applicat.h>
#include <progind.h>
#include <relation.h>
#include <utility.h>
#include <clifo.h>
#include <pconti.h>
#include "../cg/cglib02.h"
#include "saldi.h"
#include "abpcon.h"
#include "ab0.h"
#include "ab0400.h"
///////////////////////////////////////////////////////////
// TRicl_mask
///////////////////////////////////////////////////////////
class TRicl_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TRicl_mask() : TAutomask("ab0400a") { }
virtual ~TRicl_mask() { }
};
bool TRicl_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
const short id = o.dlg();
switch (id)
{
case F_ESER:
case F_PDB:
if (e == fe_modify)
{
TMask & m = o.mask();
const TString16 codpdb = m.get(F_PDB);
const int eser = m.get_int(F_ESER);
if (eser == 0 || codpdb.empty())
{
m.set(F_DAL, "");
m.set(F_AL, "");
}
else
{
TEsercizi_contabili es;
es.update();
const int anno = es.esercizio(eser).inizio().year();
const TRectype & pdb = cache().get("%PDB", codpdb);
TDate dal(pdb.get_int("I0"), pdb.get_int("I1"), anno);
TDate al(pdb.get_int("I2"), pdb.get_int("I3"), anno);
if (al < dal)
al.addyear(1);
m.set(F_DAL, dal);
m.set(F_AL, al);
}
}
break;
case F_DAL:
if (e == fe_close)
{
TMask & m = o.mask();
if (m.get(F_ESER).empty() && (m.get(F_DAL).empty() || m.get(F_AL).empty()))
return o.error_box(TR("E' necessario specificare o il codice esercizio oppure\nle date limite"));
}
break;
case F_OUTPUT:
if (e == fe_close)
{
if (o.get().empty())
return o.error_box(TR("E' necessario specificare il file di output"));
}
break;
default:
break;
}
return TRUE;
}
enum TCalc_type {_saldi = 0, _ivdircee, _analisi } ;
class TRiga_calcolo : public TObject
{
int _gruppo;
int _conto;
long _sottoconto;
int _indbil;
real _saldo_iniziale;
real _prog_dare;
real _prog_avere;
real _prog_dare_mese[12];
real _prog_avere_mese[12];
virtual TObject* dup() const { return new TRiga_calcolo(*this);}
public:
void set_conto(int g, int c, long s, int i) { _gruppo = g; _conto = c; _sottoconto = s; _indbil = i;}
void set_saldi(const TSaldo & sal);
const int gruppo() const { return _gruppo;}
const int conto() const { return _conto;}
const long sottoconto() const { return _sottoconto;}
const int indicatore_bilancio() const { return _indbil;}
real saldo_iniziale() const { return _saldo_iniziale;}
real prog_dare() const { return _prog_dare;}
real prog_avere() const { return _prog_avere;}
real prog_dare(int month) const { return _prog_dare_mese[month - 1];}
real prog_avere(int month) const { return _prog_avere_mese[month - 1];}
real saldo() const { return _saldo_iniziale + _prog_dare - _prog_avere;}
bool sezione_opposta() const;
const bool is_zero() const { return _saldo_iniziale == ZERO && _prog_dare == ZERO && _prog_avere == ZERO;}
TRiga_calcolo& copy(const TRiga_calcolo& c);
TRiga_calcolo(const TRiga_calcolo& c);
TRiga_calcolo() {}
virtual ~TRiga_calcolo() {}
};
void TRiga_calcolo::set_saldi(const TSaldo & sal)
{
_saldo_iniziale = sal.saldoini();
_prog_dare = sal.prgdare();
_prog_avere = sal.prgavere();
for (int i = 0 ; i < 12; i++)
{
_prog_dare_mese[i] = sal.prgdare(i + 1);
_prog_avere_mese[i] = sal.prgavere(i + 1);
}
}
bool TRiga_calcolo::sezione_opposta() const
{
bool reverse = FALSE;
const real s = saldo();
if (s != ZERO)
{
char sezione = s > ZERO ? 'D' : 'A';
if (_indbil == 1 || _indbil == 3)
reverse = sezione == 'A';
else
if (_indbil == 2 || _indbil == 4)
reverse = sezione == 'D';
}
return reverse;
}
TRiga_calcolo & TRiga_calcolo::copy(const TRiga_calcolo & c)
{
_gruppo = c._gruppo;
_conto = c._conto;
_sottoconto = c._sottoconto;
_indbil = c._indbil;
_saldo_iniziale = c._saldo_iniziale;
_prog_dare = c._prog_dare;
_prog_avere = c._prog_avere;
for (int i = 0; i < 12; i++)
{
_prog_dare_mese[i] += c._prog_dare_mese[i];
_prog_avere_mese[i] += c._prog_avere_mese[i];
}
return *this;
}
TRiga_calcolo::TRiga_calcolo(const TRiga_calcolo & c)
{
copy(c);
}
class TRiga_output : public TObject
{
TString _code;
real _saldo_iniziale;
real _prog_dare;
real _prog_avere;
real _prog_dare_mese[12];
real _prog_avere_mese[12];
virtual TObject* dup() const { return new TRiga_output(*this);}
public:
TRiga_output & operator +=(const TRiga_calcolo & c);
const TString & code() const { return _code;}
real saldo_iniziale() const { return _saldo_iniziale;}
real prog_dare() const { return _prog_dare;}
real prog_avere() const { return _prog_avere;}
real prog_dare(int month) const { return _prog_dare_mese[month - 1];}
real prog_avere(int month) const { return _prog_avere_mese[month - 1];}
real saldo() const { return _saldo_iniziale + _prog_dare - _prog_avere;}
char sezione_saldo() const { return saldo() > 0 ? 'D' : 'A';}
TRiga_output& copy(const TRiga_output& o);
TRiga_output(const TRiga_output& o);
TRiga_output(const char * code) : _code(code) {}
virtual ~TRiga_output() {}
};
TRiga_output & TRiga_output::operator += (const TRiga_calcolo & c)
{
_saldo_iniziale += c.saldo_iniziale();
_prog_dare += c.prog_dare();
_prog_avere += c.prog_avere();
for (int i = 0; i < 12; i++)
{
_prog_dare_mese[i] = c.prog_dare(i + 1);
_prog_avere_mese[i] = c.prog_avere(i + 1);
}
return *this;
}
TRiga_output & TRiga_output::copy(const TRiga_output & o)
{
_code = o._code;
_saldo_iniziale = o._saldo_iniziale;
_prog_dare = o._prog_dare;
_prog_avere = o._prog_avere;
for (int i = 0; i < 12; i++)
{
_prog_dare_mese[i] = o._prog_dare_mese[i];
_prog_avere_mese[i] = o._prog_avere_mese[i];
}
return *this;
}
TRiga_output::TRiga_output(const TRiga_output& o)
{
copy(o);
}
enum TFile_type { _textfile, _csvfile, _dbffile } ;
class TRicl_saldi : public TSkeleton_application
{
TRicl_mask *_mask;
TFilename _output_file;
TCalc_type _calc_type;
int _codes;
TDate _dal;
TDate _al;
bool _all_recs;
bool _months;
bool _provv;
TString _codpdb;
TString _codcms;
TArray _risultati;
TAssoc_array _output;
TString_array _output_keys;
ofstream * _file;
TExternisamfile * _dbf;
#ifdef DBG
protected:
FILE * _log;
void open_log();
void write_log(const char * line);
void close_log();
#endif
public:
virtual bool create();
virtual bool destroy();
void mask2parms(const TMask & m);
void ini2parms(const char * filename);
void calculate_clifo(const char tipo, const int gruppo, const int conto, const int indbil, const bool saldi_attuali, const TString & codcom);
void calculate();
void transform();
void get_code(const TRectype & rec, bool cee, bool reverse, TString & code);
void map(int gruppo, int conto, long sottoconto, bool reverse, TString & code);
void output();
virtual void main_loop();
TFile_type open_output();
void output_header(const bool is_commessa);
void output_line(TFile_type t, const char * key, TRiga_output & r, const bool is_commessa, TString & codcms);
void close_output(TFile_type t);
TRicl_saldi() {}
virtual ~TRicl_saldi() {}
};
#ifdef DBG
void TRicl_saldi::open_log()
{
TFilename log("ab0400.log");
_log = fopen(log,"a");
if (_log == NULL)
fatal_box(FR("Non posso aprire il file di log della conversione(%s)"), (const char *) log);
}
void TRicl_saldi::write_log(const char * line)
{
fprintf(_log,"%s\n", line);
}
void TRicl_saldi::close_log()
{
fclose(_log);
}
#endif
bool TRicl_saldi::create()
{
open_files(LF_TAB, LF_TABCOM, LF_ABPCON, LF_ABSALDI, LF_SALDI, LF_RMOV, LF_MOV,
LF_PCON, 0);
_mask = new TRicl_mask();
return TSkeleton_application::create();
}
bool TRicl_saldi::destroy()
{
delete _mask;
return TSkeleton_application::destroy();
}
void TRicl_saldi::mask2parms(const TMask & m)
{
TEsercizi_contabili es;
_calc_type = (TCalc_type) m.get_int(F_TIPO);
_codes = m.get_int(F_ESER);
_dal = m.get(F_DAL);
_al = m.get(F_AL);
if (_codes != 0 && !_dal.ok())
_dal = es.esercizio(_codes).inizio();
if (_codes != 0 && !_al.ok())
_al = es.esercizio(_codes).fine();
if (_codes == 0)
{
_codes = es.date2esc(_dal);
if (_codes == 0)
_codes = es.date2esc(_al);
}
_all_recs = m.get_bool(F_STRUCT);
_months = m.get_bool(F_MONTH);
_provv = m.get_bool(F_PROVV);
_codcms = m.get(F_COMM);
_output_file = m.get(F_OUTPUT);
_codpdb = m.get(F_PDB);
#ifdef DBG
TString line ;
write_log("---------------------------------------------------");
line = TR("Tipo di calcolo : ");
switch (_calc_type)
{
case _saldi :
line << TR("Saldi Contabili");
break;
case _ivdircee :
line << TR("IV Direttiva CEE");
break;
case _analisi :
line << TR("Analisi");
break;
default :
break;
}
write_log(line);
line = TR("Esercizio : "); line << _codes;
write_log(line);
line = TR("Codice periodo : "); line << _codpdb;
write_log(line);
line = TR("Dal : "); line << _dal.string();
write_log(line);
line = TR("Al : "); line << _al.string();
write_log(line);
line = TR("Movimenti provv.: "); line << (_provv ? "Si" : "No");
write_log(line);
line = TR("Intera struttura: "); line << (_all_recs ? "Si" : "No");
write_log(line);
line = TR("Suddiviso in mesi:"); line << (_months ? "Si" : "No");
write_log(line);
line = TR("Commessa : "); line << _codcms;
write_log(line);
line = TR("Output : "); line << ((const char *) _output_file);
write_log(line);
write_log("");
#endif
}
void TRicl_saldi::ini2parms(const char * filename)
{
TConfig c(filename, "Main");
TEsercizi_contabili es;
_calc_type = (TCalc_type) c.get_int("Tipo");
_codes = c.get_int("Esercizio");
_dal = c.get("Dal");
_al = c.get("Al");
if (_codes != 0 && !_dal.ok())
_dal = es.esercizio(_codes).inizio();
if (_codes != 0 && !_al.ok())
_al = es.esercizio(_codes).fine();
if (_codes == 0)
{
_codes = es.date2esc(_dal);
if (_codes == 0)
_codes = es.date2esc(_al);
}
_all_recs = c.get_bool("Struttura");
_months = c.get_bool("Mesi");
_provv = c.get_bool("Provvisori");
_codcms = c.get("Commessa");
_output_file = c.get("Output");
_codpdb = c.get("Periodo");
#ifdef DBG
TString line ;
write_log("---------------------------------------------------");
line = TR("Tipo di calcolo : ");
switch (_calc_type)
{
case _saldi :
line << TR("Saldi Contabili");
break;
case _ivdircee :
line << TR("IV Direttiva CEE");
break;
case _analisi :
line << TR("Analisi");
break;
default :
break;
}
write_log(line);
line = TR("Esercizio : "); line << _codes;
write_log(line);
line = TR("Codice periodo : "); line << _codpdb;
write_log(line);
line = TR("Dal : "); line << _dal.string();
write_log(line);
line = TR("Al : "); line << _al.string();
write_log(line);
line = TR("Movimenti provv.: "); line << (_provv ? "Si" : "No");
write_log(line);
line = TR("Intera struttura: "); line << (_all_recs ? "Si" : "No");
write_log(line);
line = TR("Suddiviso in mesi:"); line << (_months ? "Si" : "No");
write_log(line);
line = TR("Commessa : "); line << _codcms;
write_log(line);
line = TR("Output : "); line << ((const char *) _output_file);
write_log(line);
write_log("");
#endif
}
void TRicl_saldi::calculate_clifo(const char tipo, const int gruppo, const int conto, const int indbil, const bool saldi_attuali, const TString & codcom)
{
TRelation relcf(LF_CLIFO);
TRectype & clifo = relcf.curr();
clifo.put(CLI_TIPOCF, tipo);
TCursor cur(&relcf, "", 1, &clifo, &clifo);
long sottoconto;
TSaldo sal;
TRiga_calcolo r;
const TRecnotype items = cur.items();
cur.freeze();
TString prompt = tipo == 'C' ? TR("Ricalcolo saldi Clienti") : TR("Ricalcolo saldi Fornitori");
prompt << ' ' << gruppo << ' ' << conto;
TProgind p(items, prompt, FALSE);
for (cur = 0L; !p.iscancelled() && cur.pos() < items; ++cur)
{
sottoconto = clifo.get_long(CLI_CODCF);
if (saldi_attuali)
sal.ultima_immissione_bilancio(_codes, gruppo, conto, sottoconto, indbil, _provv ? 2 :1, FALSE);
else
sal.saldo_periodo(gruppo, conto, sottoconto, _dal, _al, indbil, _provv);
r.set_conto(gruppo, conto, sottoconto, indbil);
r.set_saldi(sal);
#ifdef DBG
TString line ;
line.format(FR("Conto %03d.%03d.%06ld - "), gruppo, conto, sottoconto);
line << TR("Saldo iniziale ") << sal.saldoini().stringa(18, 3);
line << TR(" Prog.Dare ") << sal.prgdare().stringa(18, 3);
line << TR(" Prog.Avere ") << sal.prgavere().stringa(18, 3);
line << TR(" Saldo ") << sal.saldo().stringa(18, 3);
write_log(line);
#endif
if (_all_recs || !r.is_zero())
_risultati.add(r);
p.addstatus(1L);
}
}
void TRicl_saldi::calculate()
{
TRelation relpcon(LF_PCON);
const TRectype & pcon = relpcon.curr();
TCursor cur(&relpcon, "CONTO!=0"); // Escludi i gruppi
int indbil = 0;
TSaldo sal;
TRiga_calcolo r;
TEsercizi_contabili es;
const TEsercizio & e = es.esercizio(_codes);
const bool is_commessa = _codcms.not_empty();
const bool saldi_attuali = (!is_commessa) && (!_months) && ((!_dal.ok() && !_al.ok()) || (_dal == e.inizio() && _al == e.fine()));
const TRecnotype items = cur.items();
cur.freeze();
_risultati.destroy();
TProgind p(items, TR("Ricalcolo saldi"), FALSE);
for (cur = 0L; !p.iscancelled() && cur.pos() < items; ++cur)
{
const int gruppo = pcon.get_int(PCN_GRUPPO);
const int conto = pcon.get_int(PCN_CONTO);
const long sottoconto = pcon.get_long(PCN_SOTTOCONTO);
if (sottoconto == 0L) // E' un conto
{
indbil = pcon.get_int(PCN_INDBIL);
const char tmcf = pcon.get_char(PCN_TMCF);
if (tmcf > ' ')
calculate_clifo(tmcf, gruppo, conto, indbil, saldi_attuali, _codcms);
}
else
{
if (saldi_attuali)
sal.ultima_immissione_bilancio(_codes, gruppo, conto, sottoconto, indbil, _provv ? 2 :1, FALSE);
else
sal.saldo_periodo(gruppo, conto, sottoconto, _dal, _al, indbil, _provv);
r.set_conto(gruppo, conto, sottoconto, indbil);
r.set_saldi(sal);
#ifdef DBG
TString line ;
line.format(FR("Conto %03d.%03d.%06ld - "), gruppo, conto, sottoconto);
line << TR("Saldo iniziale ") << sal.saldoini().stringa(18, 3);
line << TR(" Prog.Dare ") << sal.prgdare().stringa(18, 3);
line << TR(" Prog.Avere ") << sal.prgavere().stringa(18, 3);
line << TR(" Saldo ") << sal.saldo().stringa(18, 3);
write_log(line);
#endif
if (_all_recs || !r.is_zero())
_risultati.add(r);
p.addstatus(1L);
}
}
}
void TRicl_saldi::get_code(const TRectype &rec, bool cee, bool reverse, TString & code)
{
if (cee)
{
bool opp = reverse && rec.get_int(PCN_SEZIVDOPP) != 0;
code = rec.get(opp ? PCN_SEZIVDOPP : PCN_SEZIVD);
if (code == "0")
code.cut(0);
else
{
code << rec.get(opp ? PCN_LETTIVDOPP : PCN_LETTIVD);
code << format("%4s", (const char *) rec.get(opp ? PCN_NUMRIVDOPP : PCN_NUMRIVD));
const int numrivd = rec.get_int(opp ? PCN_NUMIVDOPP : PCN_NUMIVD);
if (numrivd != 0)
code << format("%02d", numrivd);
code.trim();
}
}
else
{
code = rec.get(PCN_CODCBL);
if (code.empty())
{
TToken_string key(rec.get(PCN_GRUPPO));
key.add(rec.get(PCN_CONTO));
key.add("");
const TRectype & conto = cache().get(LF_PCON, key);
code = conto.get(PCN_CODCBL);
}
}
}
void TRicl_saldi::map(int gruppo, int conto, long sottoconto, bool reverse, TString & code)
{
const bool no_map =_calc_type == _saldi;
if(no_map)
code.format("%03d|%03d|%06ld", gruppo, conto, sottoconto);
else
{
const bool cee =_calc_type == _ivdircee;
code.format("%d|%d|%ld", gruppo, conto, sottoconto);
const TRectype & recs = cache().get(LF_PCON, code);
get_code(recs, cee, reverse, code);
if (code.empty())
{
code.format("%d|%d", gruppo, conto);
const TRectype & recc = cache().get(LF_PCON, code);
get_code(recc, cee, reverse, code);
if (code.empty())
{
code.format("%d", gruppo);
const TRectype & recg = cache().get(LF_PCON, code);
get_code(recg, cee, reverse, code);
}
}
}
}
void TRicl_saldi::transform()
{
const int items = _risultati.items();
TString80 key;
_output.destroy();
for (int i = 0; i < items; i++)
{
const TRiga_calcolo & c = (const TRiga_calcolo &) _risultati[i];
const int gruppo = c.gruppo();
const int conto = c.conto();
const long sottoconto = c.sottoconto();
const bool reverse = c.sezione_opposta();
map(gruppo, conto, sottoconto, reverse, key);
if (key.not_empty())
{
TRiga_output * r = (TRiga_output *)_output.objptr(key);
if (r == NULL)
{
r = new TRiga_output(key);
_output.add(key, r);
}
*r += c;
}
}
}
TFile_type TRicl_saldi::open_output()
{
TString16 ext = _output_file.ext(); ext.lower();
TFile_type t;
if (ext == "dbf")
t = _dbffile;
else
if (ext == "csv")
t = _csvfile;
else
t = _textfile;
if (t == _dbffile)
_dbf = new TExternisamfile(_output_file, "ab0400.trr");
else
{
if (_output_file.exist())
remove(_output_file);
_file = new ofstream(_output_file);
}
return t;
}
void TRicl_saldi::output_line(TFile_type t, const char * key, TRiga_output & r, const bool is_commessa, TString & codcms)
{
TString descr;
const bool analisi = _calc_type == _analisi;
const bool saldi = _calc_type == _saldi;
if (analisi)
descr = cache().get(LF_ABPCON, key, ABPC_DESCRIZ);
else
if (saldi)
descr = cache().get(LF_PCON, key, PCN_DESCR);
else
descr = cache().get("%IVD", key, "S0");
real si = r.saldo_iniziale();
char fsi = si >= ZERO ? 'D' : 'A';
real s = r.saldo();
char fs = s >= ZERO ? 'D' : 'A';
real pd = r.prog_dare();
real pa = r.prog_avere();
#ifdef DBG
TString line ;
line.format(FR("Chiave %s"), key);
line << TR("Saldo iniziale ") << si.stringa(18, 3) << " " << fsi;
line << TR(" Prog.Dare ") << pd.stringa(18, 3);
line << TR(" Prog.Avere ") << pa.stringa(18, 3);
line << TR(" Saldo ") << s.stringa(18, 3) << " " << fs;
write_log(line);
#endif
TFixed_string k(key, 40);
if (t == _dbffile)
{
TRectype & rec = _dbf->curr();
rec.put("ANNOES", _codes);
k.strip("|");
rec.put("KEY", k);
rec.put("DESCR", descr);
if (is_commessa)
rec.put("CODCMS", codcms);
rec.put("SALDOI", abs(si));
rec.put("FLAGSI", fsi);
rec.put("PDARE", pd);
rec.put("PAVERE", pa);
rec.put("SALDO", abs(s));
rec.put("FLAGS", fs);
rec.put("DATAI", _dal);
rec.put("DATAF", _al);
rec.put("CODPDB", _codpdb);
if (_dbf->write(rec) != NOERR)
_dbf->rewrite(rec);
}
else
{
real tmp;
if (t == _csvfile)
{
*_file << _codes << ";";
k.replace('|', ';');
*_file << k << ";";
if (is_commessa)
*_file << codcms << ";";
*_file << "\"" << descr << "\";";
tmp = abs(si);
*_file << tmp.stringa() << ";";
*_file << fsi << ";";
if (_months)
{
for (int i = 1; i <= 12; i++)
{
*_file << r.prog_dare(i).stringa() << ";";
*_file << r.prog_avere(i).stringa() << ";";
}
}
else
{
*_file << pd.stringa() << ";";
*_file << pa.stringa() << ";";
}
tmp = abs(s);
*_file << tmp.stringa() << ";";
*_file << fs << ";";
*_file << _dal << ";";
*_file << _al << ";";
*_file << _codpdb << "\n";
}
else
{
*_file << _codes << "\t";
k.replace('|', '\t');
*_file << k << "\t";
if (is_commessa)
*_file << codcms << "\t";
*_file << descr << "\t";
tmp = abs(si);
*_file << tmp.stringa() << "\t";
*_file << fsi << "\t";
if (_months)
{
for (int i = 1; i <= 12; i++)
{
*_file << r.prog_dare(i).stringa() << "\t";
*_file << r.prog_avere(i).stringa() << "\t";
}
}
else
{
*_file << pd.stringa() << "\t";
*_file << pa.stringa() << "\t";
}
tmp = abs(s);
*_file << tmp.stringa() << "\t";
*_file << fs << "\t";
*_file << _dal << "\t";
*_file << _al << "\t";
*_file << _codpdb << "\n";
}
}
}
void TRicl_saldi::output_header(const bool is_commessa)
{
*_file << "Esercizio;";
if (_calc_type == _saldi)
*_file << "Gruppo;Conto;Sottoconto;";
else
*_file << "Esercizio;Codice;";
if (is_commessa)
*_file << "Commessa;";
*_file << "Descrizione;Saldo Iniziale;Sezione;";
if (_months)
{
for (int i = 1; i <= 12; i++)
{
*_file << itom(i) << " Dare;";
*_file << itom(i) << " Avere;";
}
}
else
{
*_file << "Progressivo Dare;";
*_file << "Progressivo Avere;";
}
*_file << "Saldo Finale;Sezione;";
*_file << "Dal ;";
*_file << "Al ;";
*_file << "Periodo di Bilancio\n";
}
void TRicl_saldi::close_output(TFile_type t)
{
if (t == _dbffile)
{
delete _dbf;
_dbf = NULL;
}
else
{
delete _file;
_file = NULL;
}
}
void TRicl_saldi::output()
{
_output_keys.destroy();
_output.get_keys(_output_keys);
_output_keys.sort();
const int items = _output_keys.items();
TFile_type t = open_output();
const bool analisi = _calc_type == _analisi;
const bool is_commessa = _codcms.not_empty();
if (t == _csvfile)
output_header(is_commessa);
if (analisi && !is_commessa)
{
TRelation relana(LF_ABSALDI);
TRectype & saldo = relana.curr();
saldo.put(ABS_CODDITTA, get_firm());
saldo.put(ABS_ANNO, _codes);
saldo.put(ABS_CODPDB, _codpdb);
TCursor cur(&relana, "", 1, &saldo, &saldo);
const TRecnotype curs_items = cur.items();
cur.freeze();
for (cur = 0L; cur.pos() < curs_items; ++cur)
relana.remove();
TProgind p(items, "Aggiornamenti Saldi analisi", FALSE);
int err = NOERR;
for (int i = 0; err == NOERR && i < items && !p.iscancelled(); i++)
{
TString & key = _output_keys.row(i);
TRiga_output & r = (TRiga_output &) _output[key];
saldo.zero();
saldo.put(ABS_CODDITTA, get_firm());
saldo.put(ABS_ANNO, _codes);
saldo.put(ABS_CODPDB, _codpdb);
saldo.put(ABS_CODCBL, key);
const real si = r.saldo_iniziale();
const char fsi = si >= ZERO ? 'D' : 'A';
saldo.put(ABS_FLDA, fsi);
saldo.put(ABS_SALDO, abs(si));
saldo.put(ABS_PDARE, r.prog_dare());
saldo.put(ABS_PAVERE, r.prog_avere());
err = relana.write();
if (err == _isreinsert)
err = relana.write();
p.addstatus(1L);
}
if (err != NOERR)
error_box("Impossibile aggiornare l'archivio saldi analisi errore n. %d", err);
}
TProgind p1(items, "Generazione output", FALSE);
for (int i = 0; i < items && !p1.iscancelled() ; i++)
{
TString & key = _output_keys.row(i);
TRiga_output & r = (TRiga_output &) _output[key];
output_line(t, key, r, is_commessa, _codcms);
p1.addstatus(1L);
}
close_output(t);
}
void TRicl_saldi::main_loop()
{
if (argc() == 2)
{
while (_mask->run() != K_QUIT)
{
#ifdef DBG
open_log();
#endif
mask2parms(*_mask);
calculate();
transform();
output();
#ifdef DBG
close_log();
#endif
}
}
else
{
#ifdef DBG
open_log();
#endif
ini2parms(argv(2));
calculate();
transform();
output();
#ifdef DBG
close_log();
#endif
}
}
int ab0400 (int argc, char* argv[])
{
TRicl_saldi main_app;
main_app.run(argc, argv, TR("Riclassificazione saldi"));
return TRUE;
}

14
src/R_10_00/ab/ab0400.h Executable file
View File

@ -0,0 +1,14 @@
// campi maschera ab0400a.uml
#define F_TIPO 101
#define F_ESER 102
#define F_PDB 103
#define F_DAL 104
#define F_AL 105
#define F_STRUCT 106
#define F_PROVV 107
#define F_OUTPUT 108
#define F_COMM 109
#define F_DCOMM 110
#define F_MONTH 111

18
src/R_10_00/ab/ab0400.trr Executable file
View File

@ -0,0 +1,18 @@
-1
14
ANNOES|9|4|0|Codice esercizio
KEY|1|20|0|Chiave
DESCR|1|70|0|Descrizione
CODCMS|1|20|0|Codice Commessa
FASCMS|1|10|0|Fase Commessa
FLAGSI|1|1|0|Saldo iniziale in <D>are, <A>vere
SALDOI|4|18|2|Saldo iniziale
PDARE|4|18|2|Progressivo dare
PAVERE|4|18|2|Progressivo avere
FLAGS|1|1|0|Saldo in <D>are, <A>vere
SALDO|4|18|2|Saldo
DATAI|5|8|0|Data inizio
DATAF|5|8|0|Data fine
CODPDB|1|3|0|Codice
1
ANNOES+KEY+CODPDB+DATAI+DATAF|

110
src/R_10_00/ab/ab0400a.uml Executable file
View File

@ -0,0 +1,110 @@
#include "ab0400.h"
TOOLBAR "topbar" 0 0 0 2
#include <stdbar.h>
ENDPAGE
PAGE "Riclassificazione" 0 2 0 0
LIST F_TIPO 20
BEGIN
PROMPT 2 1 "Tipo di calcolo "
ITEM "0|Saldi Contabili"
ITEM "1|IV Direttiva CEE"
ITEM "2|Analisi"
END
NUMBER F_ESER 4
BEGIN
PROMPT 2 3 "Esercizio "
HELP "Codice d'esercizio da assegnare"
FLAGS "ZR"
USE ESC
INPUT CODTAB F_ESER
DISPLAY "Codice esercizio" CODTAB
DISPLAY "Data inizio esercizio" D0
DISPLAY "Data fine esercizio" D1
DISPLAY "Data di scarico" D2
DISPLAY "Data chiusura esercizio" D3
OUTPUT F_ESER CODTAB
CHECKTYPE NORMAL
END
STRING F_PDB 2
BEGIN
PROMPT 2 5 "Codice periodo "
HELP "Codice della tabella periodi di bilancio"
FLAGS "U_"
USE %PDB
INPUT CODTAB F_PDB
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@40" S0
DISPLAY "gg.inizio" I0
DISPLAY "mm.inizio" I1
DISPLAY "gg.fine" I2
DISPLAY "mm.fine" I3
OUTPUT F_PDB CODTAB
CHECKTYPE NORMAL
END
DATE F_DAL
BEGIN
PROMPT 2 7 "Dal "
END
DATE F_AL
BEGIN
PROMPT 2 9 "Al "
VALIDATE DATE_CMP_FUNC > F_DAL
WARNING "La data finale deve essere maggiore alla data iniziale"
END
BOOLEAN F_STRUCT
BEGIN
PROMPT 2 11 "Intera struttura"
END
BOOLEAN F_MONTH
BEGIN
PROMPT 42 11 "Suddiviso per mesi"
END
BOOLEAN F_PROVV
BEGIN
PROMPT 2 13 "Anche i movimenti provvisori"
END
STRING F_OUTPUT 50 30
BEGIN
PROMPT 2 15 "File di output "
FSELECT ""
END
STRING F_COMM 20
BEGIN
PROMPT 2 17 "Codice commessa "
USE CMS
FIELD CODTAB
FLAGS "UZ"
INPUT CODTAB F_COMM
DISPLAY "Codice@20" CODTAB
DISPLAY "Descrizione@50" S0
OUTPUT F_COMM CODTAB
OUTPUT F_DCOMM S0
CHECKTYPE NORMAL
END
STRING F_DCOMM 70 50
BEGIN
PROMPT 2 18 "Descrizione "
USE CMS KEY 2
INPUT S0 F_DCOMM
DISPLAY "Descrizione@50" S0
DISPLAY "Codice@20" CODTAB
COPY OUTPUT F_COMM
CHECKTYPE NORMAL
END
ENDPAGE
ENDMASK

23
src/R_10_00/ab/ab1.cpp Executable file
View File

@ -0,0 +1,23 @@
#include <xvt.h>
#include <checks.h>
#include "ab1.h"
#define usage "Error - usage : %s -{0|1|2|3|4|5|6|7|8|9}"
int main(int argc, char** argv)
{
int rt = -1;
const int r = (argc > 1) ? atoi(&argv[1][1]) : -1;
switch (r)
{
case 0:
rt = ab1100(argc,argv) ; break; // Sintassi ab1 -0 %tabella -utente
case 1:
rt = ab1200(argc,argv) ; break; // Sintassi ab1 -1 -utente
default:
error_box(usage, argv[0]) ; break;
}
exit(rt);
}

7
src/R_10_00/ab/ab1.h Executable file
View File

@ -0,0 +1,7 @@
#ifndef __AB1_H
#define __AB1_H
int ab1100(int argc, char **argv);
int ab1200(int argc, char **argv);
#endif //__AB1_H

425
src/R_10_00/ab/ab1100.cpp Executable file
View File

@ -0,0 +1,425 @@
// ab1100 Stampa tabelle
//
// legge un file con estenzione .rpt che descrive la stampa.
// Vedi file leggimi.txt per il formato del file
//
#include <mask.h>
#include <printapp.h>
#include <recarray.h>
#include <utility.h>
#include <nditte.h>
#include "ab1.h"
#include "ab1100.h"
#define FOOTER_LEN 4 // se non ridefinito nel .rpt
class AB1100_application : public TPrintapp
{
TString _tabname;
TFilename _rptname;
TRelation* _rel;
TCursor *_cur;
TMask* _msk;
TString _maskname;
int _logicnum;
TString_array _string_roman, _string_compound;
TString_array _field_roman, _field_compound;
// bool _stampa_registri;
// bool _stampa_ca7; //tabella causali 770
bool _tabella_comune;
public:
virtual bool user_create() ;
virtual bool user_destroy() ;
virtual bool set_print(int) ;
virtual void set_page(int, int);
virtual bool preprocess_page (int, int);
virtual bool preprocess_print(int file, int counter);
void set_headers();
void set_rows();
void set_footers();
void set_translations();
void set_relations();
AB1100_application() {}
virtual ~AB1100_application() {}
};
bool AB1100_application::set_print(int)
{
TRectype from(_rel->lfile().curr()); from.zero();
TRectype to (from);
if (_msk->run() == K_ENTER)
{
const int campi_maschera = _msk->fields();
for (int i = 0; i < campi_maschera; i++)
{
const TMask_field& campo_maschera = _msk->fld(i);
const char* val = campo_maschera.get();
if (*val)
{
const TFieldref* campo_ref = campo_maschera.field();
if (campo_ref != NULL && campo_ref->ok())
{
TDate d;
const bool is_date_field = campo_maschera.class_id() == CLASS_DATE_FIELD;
if (is_date_field)
d=val;
if (campo_maschera.in_group(1)) campo_ref->write(is_date_field ? d.string(ANSI) : val, from);
else
if (campo_maschera.in_group(2)) campo_ref->write(is_date_field ? d.string(ANSI) : val, to);
}
}
}
_cur->setregion (from, to);
set_headers();
return TRUE;
}
return FALSE;
}
void AB1100_application::set_page (int , int )
{
_string_roman.destroy();
_field_roman.destroy();
_string_compound.destroy();
_field_compound.destroy();
set_rows();
}
bool AB1100_application::preprocess_page(int , int)
{
const int items = _field_roman.items();
if (items > 0)
{
for (int i = 0; i < items; i++)
{
TString& fn = _field_roman.row(i);
TFieldref fld(fn, 0);
TString& s = _string_roman.row(i);
const int n = atoi(fld.read(*_rel));
s = itor(n);
}
}
const int compound = _field_compound.items();
if (compound > 0)
// Scorre le righe settate
for (int i = 0; i < compound; i++)
{
TToken_string f(_field_compound.row(i),'+'); // campo composto
TString& s = _string_compound.row(i); // riga da stampare
s.cut(0); // Reset the row...
bool compile_row = TRUE;
const int cmp_items = f.items();
// Scorre gli elementi della riga
for (int j = 0; j < cmp_items; j++)
{
// compone la stringa totale
TString xx(f.get(j));
if (xx[0] != '"') // se non e' una costante stringa legge il valore
{
TFieldref fld(xx,0);
xx = fld.read(*_rel);
if (xx.empty()) compile_row = FALSE;
else compile_row = TRUE;
}
else
{
xx.ltrim(1);xx.rtrim(1);
}
if (compile_row)
s << xx; // appende alla stringa il valore ricavato (se il campo e' vuoto non appende nemmeno la stringa fissa)
}
}
// Stampa tabella registri. Calcolo: pagine residue = pagine - stampate
return TRUE;
}
void AB1100_application::set_headers()
{
TString NomeTabella, sep, formato_intesta, testo_intesta;
int LungRiga, riga_intesta=0, last_riga=1;
TToken_string line;
TString256 riga;
reset_header ();
TScanner rpt(_rptname);
rpt.paragraph("Headers");
// Leggo la lunghezza della riga (usata per centrare l'intestazione)
line = rpt.line();
LungRiga = line.get_int();
riga.spaces(LungRiga);
// Senno' nella stampa a 80 non ci sta ditta e data
// Leggo il nome della tabella
line = rpt.line();
NomeTabella = line.get();
// Sulla prima riga di intestazione metto la ditta, la data e la pagina
if (!_tabella_comune)
{
TString8 codditta; codditta << get_firm();
TString80 ragsoc = cache().get(LF_NDITTE, codditta, NDT_RAGSOC);
if (LungRiga < 100) ragsoc.cut(40);
riga.overwrite(format(FR("Ditta %4ld %s"), atol(codditta),(const char *)ragsoc));
}
riga.overwrite (FR("Data @< Pag. @#"), riga.len()-22);
set_header (last_riga++, "%s", (const char *)riga);
// Centro il nome della tabella
// Per la stampa registri non va centrato.
// Lo lascio anche per le altre stampe
// if (_stampa_registri)
NomeTabella.left_just (LungRiga);
set_header (last_riga++, "@b%s", (const char *)NomeTabella);
line = rpt.line();
while ( (line != "") && (line[0] != '[') )
{
riga_intesta = atoi (line.get());
formato_intesta = line.get();
testo_intesta = (const char *) line.get();
if (riga_intesta)
set_header (last_riga+riga_intesta, (const char *)formato_intesta,
(const char *)testo_intesta);
line = rpt.line();
}
if (riga_intesta) last_riga += riga_intesta;
last_riga++;
//set_header (last_riga, (const char *)sep);
sep.fill(' ');
set_header (last_riga, (const char *)sep);
set_background(format("W2l{1,3,%d,3}l{1,%d,%d,%d}", LungRiga, last_riga, LungRiga, last_riga));
}
void AB1100_application::set_rows()
{
TToken_string line;
TFieldref campo;
int from = 0, to = 0, riga_record;
TString formato_campo, picture;
const char * name = NULL;
TScanner rpt(_rptname);
rpt.paragraph("Rows");
line = rpt.line();
while ( (line != "") && (line[0] != '[') )
{
riga_record = line.get_int();
TString s(line.get());
int logicnum = _logicnum;
const bool is_compound = s.find('+') >= 0; // Controlla se e' una stringa composta (usare #t nel formato)
if (!is_compound)
{
campo = s;
from = campo.from();
to = campo.to();
name = campo.name();
if (campo.file() != 0)
logicnum = campo.file();
}
formato_campo = line.get();
formato_campo.trim();
formato_campo.lower();
const int p = formato_campo.find("@m");
if (p != -1 && !is_compound)
{
formato_campo.cut(p);
formato_campo << "#t";
_string_roman.add("");
_field_roman.add(s);
const int last = _string_roman.items() - 1;
set_row (riga_record, formato_campo, _string_roman.objptr(last));
}
else if (!is_compound)
{
if (formato_campo.find("@pn"))
picture = line.get();
else
picture = "";
if (to == -1)
if (picture != "")
set_row (riga_record, formato_campo, FLD(logicnum,name,picture) );
else
set_row (riga_record, formato_campo, FLD(logicnum,name) );
else
set_row (riga_record, formato_campo, FLD(logicnum,name,from,to) );
}
else
{
_string_compound.add("");
_field_compound.add(s);
const int last = _string_compound.items() - 1;
set_row (riga_record, formato_campo, _string_compound.objptr(last));
}
line = (const char *) rpt.line();
}
}
void AB1100_application::set_footers()
{
TToken_string line;
int footer_len, riga;
TString formato, testo;
reset_footer();
TScanner rpt(_rptname);
rpt.paragraph("Footers");
line = rpt.line();
footer_len = line.get_int();
if (footer_len != 0)
{
printer().footerlen(footer_len);
line = rpt.line();
}
while ( (line != "") && (line[0] != '[') )
{
riga = line.get_int();
formato = line.get();
testo = line.get();
set_footer (riga, (const char *)formato, (const char*)testo);
line = rpt.line();
}
}
void AB1100_application::set_translations()
{
TString campo, from, to;
TToken_string line;
int logicnum;
TScanner rpt(_rptname);
rpt.paragraph("Translations");
line = rpt.line();
while ( (line != "") && (line[0] != '[') )
{
logicnum = line.get_int();
campo = line.get();
from = line.get();
to = line.get();
set_translation (logicnum, (char*)(const char *)campo, (char*)(const char *)from, (char*)(const char *)to);
line = rpt.line();
}
}
void AB1100_application::set_relations()
{
TToken_string line("", ';');
TString tab(16), expr(40);
int key, linkto, alias, logicnum;
TScanner rpt(_rptname);
rpt.paragraph("Relations");
line = rpt.line();
while ( (line != "") && (line[0] != '[') )
{
tab = line.get();
logicnum = atoi(tab);
expr = line.get();
key = line.get_int();
if (key == 0) key = 1;
linkto = line.get_int();
alias = line.get_int();
if (logicnum > 0)
_rel->add(logicnum, expr, key, linkto, alias);
else
_rel->add(tab, expr, key, linkto, alias);
line = rpt.line();
}
}
bool AB1100_application::user_create()
{
_tabname = argv(2);
TString16 t(_tabname);
_tabella_comune = (t[0] == '%');
if (_tabella_comune)
t.ltrim(1);
_rptname << "batb" << t << ".rpt" ;
if (!fexist(_rptname))
return error_box("Impossibile aprire il file '%s'", (const char*)_rptname);
// Flag per la stampa tabella registri
_tabname.upper();
_rel = new TRelation (_tabname);
_cur = new TCursor (_rel);
_maskname << "bast" << t;
_msk = new TMask (_maskname) ;
add_cursor (_cur);
add_file (_tabname);
_logicnum = _cur->file().num();
reset_print ();
printer().footerlen (FOOTER_LEN);
for (int i=1; i <= FOOTER_LEN; i++) set_footer(i, "%s", " ");
#ifdef DBG1
set_fillchar ('.');
#endif
set_relations();
return TRUE;
}
bool AB1100_application::preprocess_print(int file, int counter)
{
set_headers();
set_footers();
set_translations();
return TRUE;
}
bool AB1100_application::user_destroy()
{
delete _msk;
delete _cur;
delete _rel;
return TRUE;
}
int ab1100(int argc, char** argv)
{
AB1100_application a;
a.run(argc, argv, TR("Stampa tabella"));
return 0;
}

36
src/R_10_00/ab/ab1100.h Executable file
View File

@ -0,0 +1,36 @@
#ifndef __AB1100_H
#define __AB1100_H
#define F_INIZIO0 100
#define F_INIZIO1 101
#define F_INIZIO2 102
#define F_INIZIO3 103
#define F_INIZIO4 104
#define F_INIZIO5 105
#define F_INIZIO6 106
#define F_INIZIO7 107
#define F_INIZIO8 108
#define F_INIZIO9 109
#define F_INIZIO10 110
#define F_FINE1 201
#define F_FINE2 202
#define F_FINE3 203
#define F_FINE4 204
#define F_FINE5 205
#define F_FINE6 206
#define F_FINE7 207
#define F_FINE8 208
#define F_FINE9 209
#define F_FINE10 210
#define F_CODDITTA 211
#define F_RAGSOC 212
#define F_DATASTAMPA 213
#endif

57
src/R_10_00/ab/ab1200.cpp Executable file
View File

@ -0,0 +1,57 @@
// ab1200 Stampa Piano dei Conti
#include <mask.h>
#include <form.h>
#include <applicat.h>
#include <urldefid.h> //Definisce BAR_ITEM(1)
#include "ab1.h"
#include "ab1200.h"
class AB1200_application : public TSkeleton_application
{
public:
virtual void main_loop(); //Controlla il menu
AB1200_application() {} //Costruttore
virtual ~AB1200_application() {} //Distruttore
};
void AB1200_application::main_loop()
{
TForm f("AB1200"); //form: AB1200.frm
TMask m("AB1200"); //machera: AB1200.uml
while (m.run() != K_QUIT) //Finchè non viene premuto un tasto di uscita
{
TString cod_from, cod_to; //Dichiarazione
cod_from=m.get(F_INIZIO); //Inizializzo con quello che preleva dal campo della maschera
cod_to=m.get(F_FINE);
//Dati validi: (cod_from <= cod_to) and (cod_to = "vuoto")
bool err = ((cod_from > cod_to) && (cod_to != "") );
if (err)
error_box(TR("Il campo iniziale deve essere vuoto o minore del campo finale"));
else
{
TCursor* cur = f.cursor(); //Ritorna il cursore corrente (oggetto)
TRectype rec_from(cur->curr()); //TRectype: classe per la definizione del tipo record
//rec_from è l'oggetto a cui associo l'indice corrente
rec_from.zero(); //lo vuoto
rec_from.put("CODCBL",cod_from); //e lo riempio con il campo contenuto nel database all'indice iniziale
TRectype rec_to(cur->curr()); //creo un nuovo oggetto a cui associare l'indice
rec_to.zero(); //lo vuoto
if (cod_to.not_empty()) //se cod_to (letto dal campo della tabella) non è vuoto
rec_to.put("CODCBL",cod_to); //gli inserisco l'indice finale letto
//altrimenti va fino alla ifne del file
cur->setregion(rec_from,rec_to); //all'indice associo la regine di stampa
f.print(); //Stampa
}
}
}
int ab1200(int argc, char** argv)
{
AB1200_application a;
a.run(argc, argv, TR("Stampa Piano dei Conti"));
return 0;
}

113
src/R_10_00/ab/ab1200.frm Executable file
View File

@ -0,0 +1,113 @@
//stampa piano dei conti
USE 78
END
DESCRIPRION
BEGIN
78->* "Piano dei Conti"
END
GENERAL
BEGIN
OFFSET 0 0
FONT "Courier New"
SIZE 7
END
SECTION HEADER ODD 6
STRINGA 1 80
BEGIN
KEY "Separatore (iniziale)"
PROMPT 1 3 "--------------------------------------------------------------------------------"
END
STRINGA 2 12
BEGIN
KEY "Intestazione (Codice)"
PROMPT 1 4 "Codice"
END
STRINGA 3 40
BEGIN
KEY "Intestazione (Descrizione)"
PROMPT 25 4 "Descrizione"
END
NUMERO 4 5
BEGIN
KEY "Intestazione (I.b.)"
PROMPT 53 4 "I.b."
END
STRINGA 5 12
BEGIN
KEY "Intestazione (Codcontr)"
PROMPT 63 4 "Cod. Contr."
END
STRINGA 6 6
BEGIN
KEY "Intestazione (Sosp.)"
PROMPT 75 4 "Sosp."
END
STRINGA 7 80
BEGIN
KEY "Separatore (finale)"
PROMPT 1 5 "--------------------------------------------------------------------------------"
END
END
//Il -2 significa che stampa su 1 o 2 righe secondo quello che devo stampare
SECTION BODY ODD -2
STRINGA 2 12
BEGIN
KEY "Codice"
PROMPT 1 1 ""
FIELD 78->CODCBL
END
//Sintassi: TIPO id lunghezza_per_riga numero_righe
STRINGA 3 40 2
BEGIN
KEY "Descrizione"
PROMPT 14 1 ""
FIELD 78->DESCRIZ
END
NUMERO 4 1
BEGIN
KEY "Indicatore"
PROMPT 55 1 ""
FIELD 78->INDBIL
END
STRINGA 5 12
BEGIN
KEY "Cod. contr."
PROMPT 63 1 ""
FIELD 78->CODCONTR
END
STRINGA 6 1
BEGIN
KEY "Sospeso"
PROMPT 76 1 ""
FIELD 78->SOSPESO
END
END
END

13
src/R_10_00/ab/ab1200.h Executable file
View File

@ -0,0 +1,13 @@
#ifndef __AB1200_H
#define __AB1200_H
#define F_INIZIO 100
#define F_FINE 101
#define F_INIZIO1 102
#define F_FINE1 103
#endif

47
src/R_10_00/ab/ab1200.uml Executable file
View File

@ -0,0 +1,47 @@
#include "ab1200.h"
PAGE "Stampa Piano dei Conti" -1 -1 50 8
NUMBER F_INIZIO 12
BEGIN
PROMPT 3 1 "Da codice "
HELP "Codice da cui iniziare a stampare. Vuoto = inizio archivio"
USE LF_ABPCON
INPUT CODCBL F_INIZIO
DISPLAY "Codice@12" CODCBL
DISPLAY "Descrizione@40" DESCRIZ
DISPLAY "I.B.@5" INDBIL
// DISPLAY "D/M@5" DETT
DISPLAY "Con.C.@12" CODCONTR
DISPALY "SOSP.@5" SOSPESO
OUTPUT F_INIZIO CODCBL
GROUP 1
FIELD CODCBL
FLAGS "ZRU"
END
NUMBER F_FINE 12
BEGIN
PROMPT 4 3 "A codice "
HELP "Codice a cui terminare la stampa. Vuoto = fine archivio"
COPY USE F_INIZIO
INPUT CODCBL F_FINE
COPY DISPLAY F_INIZIO
OUTPUT F_FINE CODCBL
GROUP 2
FIELD CODCBL
FLAGS "ZRU"
END
BUTTON DLG_OK 10 2
BEGIN
PROMPT -12 -1 ""
END
BUTTON DLG_QUIT 10 2
BEGIN
PROMPT -22 -1 ""
END
ENDPAGE
ENDMASK

25
src/R_10_00/ab/ab2.cpp Executable file
View File

@ -0,0 +1,25 @@
//AB2.CPP: Menù principale
#include <xvt.h>
#include <checks.h>
#include "ab2.h" //nome delle applicazione
#define usage "Error - usage : %s -{0|1|2|3|4|5}"
int main(int argc,char **argv)
{
int n = (argc > 1) ? atoi(argv[1]+1) : -1;
switch (n)
{
case 0:
ab2100(argc,argv); break; //Trasferimento e Ricezione
// case 1:
// ab2200(argc,argv); break; //Scarico archivi
default:
error_box(usage, argv[0]) ;
}
exit(0);
}

12
src/R_10_00/ab/ab2.h Executable file
View File

@ -0,0 +1,12 @@
//AB2.H: Nome delle applicazioni
#ifndef __AB2_H
#define __AB2_H
int ab2100(int argc, char **argv);
int ab2101(int argc, char **argv);
int ab2102(int argc, char **argv);
//int ab2200(int argc, char **argv);
#endif //__AB2_H

180
src/R_10_00/ab/ab2100.cpp Executable file
View File

@ -0,0 +1,180 @@
//AB2100.CPP: Ricezione-Trasferimetno tabelle
#include <xvt.h>
#include <checks.h>
#include <string.h>
#include "ab2100a.h"
#include "ab2.h"
#include "ab2100.h"
/* ********************************************************************************************************* */
/* TTrasfer */
/*********************************************************************************************************** */
TObject_reception *TRicezione::set_transfer(int tipo_ricezione ,const TFilename & percorso, const TString & config_name)
{
if (_rice != NULL)
delete _rice;
switch (tipo_ricezione)
{
case RICEZIONE_INTERNA:
_rice = new TObject_reception(percorso);
break;
case RICEZIONE_AS400:
_rice = new TRicezione_AS400(percorso);
break;
case RICEZIONE_USER_DEFINED:
_rice = new TRicezione_userdef(config_name,percorso);
break;
}
return _rice;
}
int ab2100(int argc, char **argv)
{
char *rt = argv[2]+1; //Leggo se è richiesta la ricezine (r/R) o il trasferimento (t/T)
*rt=toupper(*rt);
switch (*rt)
{
case 'R': //Ricezione
{
ab2101(argc,argv);
break;
}
case 'T': //Trasferimento
{
ab2102(argc,argv);
break;
}
default:
error_box (TR("Sintassi: \n -0 -R -<utente> per ricezione \n -0 -T -<utente> per trasferimenTo"));
}
return 0;
}
TAdditional_car::TAdditional_car() :
TRectype(LF_CARADD)
{
}
void TAdditional_car::put_str(const char* fieldname, const char* val)
{
if (strcmp(fieldname,ABCA_ID)==0)
{
static TString16 id;
CHECK(length(ABCA_ID)<=16,"ID in CARADD deve essere max lungo 16");
id = val;
id.right_just(length(ABCA_ID));
TRectype::put_str(fieldname, (const char *)id);
} else
TRectype::put_str(fieldname, val);
}
bool TAdditional_car::same_as(real other_id)
{
bool r;
//TLocalisamfile ca(LF_CARADD);
TAdditional_cars ca;
ca.put(ABCA_ID,other_id);
ca.read();
real id = get_real(ABCA_ID);
put(ABCA_ID,ca.get(ABCA_ID));
r= (*this == ca.curr());
put(ABCA_ID,id);
return r;
}
TAdditional_cars::TAdditional_cars(TFilelock lockmode) :
TLocalisamfile (LF_CARADD)
{
set_curr(new TAdditional_car());
if (lockmode==_excllock)
{
lock(); //Il file è già aperto: gli faccio un lock
if (last()==NOERR)
_lastid=get_long(ABCA_ID);
else
_lastid=0;
} else
_lastid=-1;
}
long TAdditional_cars::lastid()
{
if (_lastid>=0)
{
return _lastid;
} else {
TLocalisamfile ca(LF_CARADD);
if (ca.last()==NOERR)
return atol(get(ABCA_ID));
else
return 0;
}
}
int TAdditional_cars::write()
{
int err;
if (_lastid>=0)
{
curr().put(ABCA_ID,++_lastid);
err=TLocalisamfile::write();
} else {
do {
curr().put(ABCA_ID,lastid()+1);
err=TLocalisamfile::write();
} while (err==_isdupkey);
}
return err;
}
/***********************/
long TAdditional_cols::_lastid = 0;
int TAdditional_cols::write()
{
int err = NOERR;
bool scrivo = FALSE;
for (int i = curr().items(); (i > 1) && (!scrivo); i--) //Estraggo il campo
{
const char * name_field = curr().fieldname(i);
const char * str = "";
if (name_field) //Inizializzo la stringa solo se il puntatore non è nullo
str = curr().get(name_field);
if (strlen(str) > 0) //Se la stringa è stata inizilizzata a qualcosa entro per controllare
{
for (int ii = 0; str[ii]; ii++)
{//scorro il contenuto del campo per controllare se è vuoto
if ((str[ii] != ' ') && (str[ii] != '0'))
{
scrivo = TRUE; //se trovo qualcosa di "non vuoto" setto il flag di scrittura
break;
}
}
}
}
if (scrivo)
{
do {
curr().put(ABCD_ID,++_lastid);
err=TLocalisamfile::write();
} while (err==_isdupkey);
err=TLocalisamfile::write();
}
else
curr().put(ABCD_ID,0); //Il record non è stato scritto ma devo inserire nella chiave del rocord
//l'indice (=0) poichè questo andrà inserito in RELANA
return err;
}

343
src/R_10_00/ab/ab2100.h Executable file
View File

@ -0,0 +1,343 @@
//AB2100.H: Classe principale e definizione di costanti
#ifndef _AB2100_H
#ifndef __APPLICAT_H
#include <applicat.h> //Definizione della classe TApplication
#endif
#ifndef __FILETEXT_H
#include <filetext.h>
#endif
#ifndef __MASK_H
#include <mask.h> //Definizione della maschera
#endif
#define ID_NULLO 0
//Costanti di definizione dei tipi record
#define MOVIMENTO1 "MOVI1"
#define MOVIMENTO2 "MOVI2"
#define MOVIMENTO3 "MOVI3"
#define MOVIMENTO4 "MOVI4"
#define MOVIMENTO5 "MOVI5"
#define TIPO_TABELLA_PERIODI "TBBBD"
#define SIGLA_TABELLA_PERIODI "BB"
#define TIPO_SRELAZ "STABI"
#define TIPO_VOCI "ATAB2"
#define TIPO_VOCI "ATAB2"
//Costanti di posizionamento nel record_text
#define SIGLA_TAB_PER 1
//Costanti di posizionamento nel record_text dei MOVIMENTI e DETTAGLI
#define CODICE_DITTA_MOVDETT 1
#define ANNO_BILANCIO_MOVDETT 2
#define CODICE_PERIODO_MOVDETT 3
#define CODICE_TABELLA_MOVDETT 4
#define CONTO_COGE_MOVDETT 5
#define PROGRESSIVO_DETT_MOVDETT 6
#define NUMERO_REG_MOVDETT 8
#define NUMERO_RIGA_MOVDETT 9
#define SALDO_INIZIO_ANNO_MOVDETT 13
#define PROGRESSIVO_DARE_MOVDETT 14
#define PROGRESSIVO_AVERE_MOVDETT 15
#define RICLASSIFICAZIONE_DARE_MOVDETT 16
#define RICLASSIFICAZIONE_AVERE_MOVDETT 17
#define FLAG_DA_MOVDETT 17
#define IMPORTO_MOVDETT 19
#define FLAG_RICLASSIFICAZIONE_MOVDETT 21
#define SALDO_INIZIO_ANNO_SLD_MOVDETT 9
#define PROGRESSIVO_DARE_SLD_MOVDETT 10
#define PROGRESSIVO_AVERE_SLD_MOVDETT 11
#define RICLASSIFICAZIONE_DARE_SLD_MOVDETT 12
#define RICLASSIFICAZIONE_AVERE_SLD_MOVDETT 13
//Costanti di posizionamento nel record_text per VOCI
#define TIPO_VOCE_VOCI 6
#define NCA_VOCI 4
#define CODVC_VOCI 1
#define CODCOMP_ANA_VOCI 2
#define DESCR1_VOCI 5
#define DESCR2_VOCI 43
#define VOCI_INCIDENZA 41
//Costanti di posizionamento nel record_text per SOTTORELAZIONI
#define CODAN_SOTTOREL 1
#define CODVC_SOTTOREL 2
#define NCOMP_SOTTOREL 3
#define NSREL_SOTTOREL 5
//Costanti tipi di ricesione
#define RICEZIONE_INTERNA 1
#define RICEZIONE_AS400 2
#define RICEZIONE_USER_DEFINED 3
//Definizione dei flag
#define FLAG_COGE '1'
#define FLAG_DETT '2'
#define FLAG_MOVIMENTO '3' // così i movs sono alla fine
#define FLAG_INDICE "I"
#define FLAG_SOTTOD "S"
#define FLAG_COMPOSTA "C"
#define FLAG_ANALISI "A"
#define FLAG_VOCI "V"
#define FLAG_COGE_CG "CG"
#define FLAG_DETT_DT "DT"
#define FLAG_CLIENTE_CL "CL"
#define FLAG_FORNITORE_FO "FO"
#define FLAG_MOVIMENTO_MO "MO" // così i movs sono alla fine
//Definizioni di constanti per il record di testata
#define RECORD_TESTA "1"
#define ABILITATO "X"
#define AB_PIANO_CONTI 2
#define AB_PERIODI_BIL 3
#define AB_ANALISI 4
#define AB_SALDI 8
#define AB_DETT 9
#define AB_MOV 10
class TAlbero_record : public TAssoc_array
{
static TToken_string wrk_string;
public:
void dept_first(TToken_string key, TRectype * padre, TRectype * prec, int &curr_id, TString_array & allkeys, TToken_string ** prog_key);
TToken_string& cerca_fratello (TToken_string &key, TString_array& allkeys, TToken_string ** next_key);
TToken_string& cerca_figlio (TToken_string &key, TString_array& allkeys, TToken_string ** next_key);
TAlbero_record() {}
virtual ~TAlbero_record(){}
};
class TFile_text_AS400: public TFile_text
{
TAssoc_array _last_id;
// static long _idcaradd;
long _idncomp;
TString16 _tipo_bilancio;
//long _idcoldich;
TString _codvc_prec;
inline const TString & get_tipo_bil() const {return _tipo_bilancio;}
protected:
// virtual void preformat_field(TRelation& rel,const TFieldref&field,const TRecord_text& rec,TString &str);
virtual void preformat_field(const TFieldref&field,TString &str,TRelation& rel,const TString &tipo_tr);
void cambia_anno(TString& str);
void cambia_data(TString& str);
virtual bool pre_writerel(TRelation& rel,const TRecord_text& rec);
void scrivi_temp_link(TRelation& rel,const TRecord_text& rec);
void aggiorna_rel_link(TLocalisamfile &relvoc);
public:
void set_tipo_bilancio(const TString & tipo_bil) {_tipo_bilancio = tipo_bil;}
TFile_text_AS400(const char* file_name, const char* set_config_name);
virtual ~TFile_text_AS400() {}
};
class TObject_reception:public TObject
{
protected:
TFile_text* _trasfile; //File di testo da cui ricevere
public:
TFile_text * trans_file() {return _trasfile;}
virtual void ricevi(TMask &);
TObject_reception() {_trasfile = NULL;}
TObject_reception(const TFilename &percorso) ;
virtual ~TObject_reception() {}
};
//Classe derivata per la ricezione
class TRicezione_AS400 : public TObject_reception
{
private:
void build_balancetree(int);
void build_ana_tree(long&, TRectype&, TRectype*, TRectype*, TAssoc_array&);
void build_relana(TString&, const TMask&, const TFilename&);
void naviga_array(TAlbero_record &a);
void scrivi_array(TAssoc_array &s_rec, int);
protected:
TFile_text_AS400 *trasfile() {return (TFile_text_AS400 *)_trasfile;}
virtual void leggi_temp_link(TRectype& cur_rec,TToken_string& k);
//Questa funzione è da usare solo in fase di debug
#ifdef DBG
void print_ana_tree(int & level, TRectype&,FILE * stream);
#endif
public:
virtual void ricevi(TMask &);
TRicezione_AS400(const TFilename &percorso);
virtual ~TRicezione_AS400() {}
};
//Classe derivata per la ricezione
class TRicezione_userdef : public TObject_reception
{
public:
//virtual void ricevi(TMask &);
TRicezione_userdef(const TString & config, const TFilename &percorso) ;
virtual ~TRicezione_userdef() {}
};
//classe derivata nella quale viene gestita la funzione di trasferimento
class TTrasfer: public TSkeleton_application
{
// private:
// TArray _files;
protected:
// TFile_text* _trasfile; //File di testo
// virtual bool menu(MENU_TAG) pure; //Gli dico che non è implementata in questa classe, ma obbligatoriamente in un'altra
virtual void main_loop() pure; //Gli dico che non è implementata in questa classe, ma obbligatoriamente in un'altra
//Controlla che il percorso e il file specificati esistono
static bool inseriscipercorso(TMask_field& f, KEY k);
public:
TTrasfer() {}
virtual ~TTrasfer() {}
};
class TRicezione:public TTrasfer
{
private:
TArray _files;
TObject_reception *_rice;
protected:
// virtual bool create();
// virtual bool destroy();
// virtual bool menu(MENU_TAG);
virtual void main_loop();
public:
//Seleziona da quale file prelevare le informazioni del tracciato record
// void set_config_name(TString&,TMask&);
TObject_reception *set_transfer(int tipo_ricezione ,const TFilename & percorso_temp, const TString & config_file_temp);
TObject_reception *transfer() {return _rice;}
TFile_text * trans_file() {return _rice->trans_file();}
TRicezione() {_rice=NULL;}
virtual ~TRicezione() {}
};
class TObject_send:public TObject
{
protected:
TFile_text* _trasfile; //File di testo da cui ricevere
public:
TFile_text * trans_file() {return _trasfile;}
virtual void converti(int);
virtual void converti(int main_file,const char * tabname);
TObject_send() {_trasfile = NULL;}
TObject_send(const TFilename &percorso);
virtual ~TObject_send() { delete _trasfile;}
};
//Classe derivata per il trasferimento
class TInvio:public TTrasfer
{
TObject_send *_invio;
protected:
//virtual bool menu(MENU_TAG);
virtual void main_loop();
static bool inseriscipercorso(TMask_field& f, KEY k);
public:
TInvio() {}
virtual ~TInvio() {}
};
class TInvio_AS400:public TObject_send
{
protected:
void trasferisci_albero(TRectype &,TRecord_text&, TAssoc_array&);
bool cerca_padre(TLocalisamfile &, TRectype &);
long my_num(TLocalisamfile&, TAssoc_array&);
bool mov_da_scrivere(TRectype &);
void formatta(TRecord_text&,TRectype&,int&);
public:
virtual void converti(int);
TInvio_AS400(const TFilename &percorso);
virtual ~TInvio_AS400() {}
};
class TInvio_user_defined:public TObject_send
{
public:
// virtual void converti(int) {} //DA definire
TInvio_user_defined(const TString & config, const TFilename &percorso);
virtual ~TInvio_user_defined() {}
};
// **********************
// da spostare in ablib01
class TAdditional_car: public TRectype
{
protected:
virtual void put_str(const char* fieldname, const char* val);
public:
bool same_as(real id);
TAdditional_car();
virtual ~TAdditional_car() {}
};
/***************************/
class TAdditional_cars: public TLocalisamfile
{
long _lastid; // usato in caso di lock
public:
long lastid();
TAdditional_car & current()
{return (TAdditional_car & )(TLocalisamfile::curr());}
virtual int write();
//int write();
TAdditional_cars(TFilelock lockmode=_manulock);
virtual ~TAdditional_cars() {}
};
class TAdditional_col: public TRectype
{
public:
TAdditional_col();
virtual ~TAdditional_col() {}
};
class TAdditional_cols: public TLocalisamfile
{
static long _lastid;
public:
//long lastid();
virtual int write();
TAdditional_cols();
virtual ~TAdditional_cols() {}
};
#endif //_AB2100_H

22
src/R_10_00/ab/ab2100a.h Executable file
View File

@ -0,0 +1,22 @@
//AB2100A.H: Campi della maschera
#ifndef __AB2100A_H
#define __AB2100A_H
#define F_PERCORSO 200
#define F_TESTO_PERCORSO 201
#define F_TESTO_SELEZIONE 202
#define F_PIANO_CONTI 203
#define F_PERIODI_BILANCI 204
#define F_ANALISI 205
#define F_TIPO_RICE 206
#define F_TESTO_UTENTE 207
#define F_PERCORSO_UTENTE 208
#define F_MOVIMENTI 209
#define F_SALDI 210
#define F_VOCI 211
#define F_RELAZ 212
#define F_SRELAZ 213
#define F_TESTO_TIPOBIL 214
#define F_TIPO_BILANCIO 215
#endif //__AB2100A_H

2536
src/R_10_00/ab/ab2100a.ini Executable file

File diff suppressed because it is too large Load Diff

153
src/R_10_00/ab/ab2100a.uml Executable file
View File

@ -0,0 +1,153 @@
#include "ab2100a.h"
TOOLBAR "" 0 19 0 3
BUTTON DLG_OK 10 2
BEGIN
PROMPT -13 -11 ""
END
BUTTON DLG_QUIT 10 2
BEGIN
PROMPT -22 -11 ""
END
ENDPAGE
PAGE "Ricezione e Invio" -1 -1 0 20
GROUPBOX DLG_NULL 76 5
BEGIN
PROMPT 1 0 ""
FLAGS "R"
END
TEXT F_TESTO_PERCORSO
BEGIN
PROMPT 2 1 "Percorso completo del file di testo:"
END
STRING F_PERCORSO 80 70
BEGIN
PROMPT 2 3 ""
FIELD PERCORSO
CHECKTYPE REQUIRED
END
TEXT F_TESTO_SELEZIONE
BEGIN
PROMT 2 7 "Selezionare le tabelle:"
END
LISTBOX F_TIPO_RICE 15
BEGIN
PROMPT 2 5 "Tipo: "
ITEM "1|WINDOWS"
MESSAGE DISABLE,F_PERCORSO_UTENTE|DISABLE,F_TESTO_UTENTE|HIDE, F_TIPO_BILANCIO
ITEM "2|AS400"
MESSAGE DISABLE,F_PERCORSO_UTENTE|DISABLE,F_TESTO_UTENTE|SHOW, F_TIPO_BILANCIO
ITEM "3|USER DEFINED"
MESSAGE ENABLE,F_PERCORSO_UTENTE|DISABLE,F_TESTO_UTENTE|SHOW, F_TIPO_BILANCIO
END
TEXT F_TESTO_UTENTE
BEGIN
PROMPT 2 17 "Percorso completo del file di configurazione:"
END
STRING F_PERCORSO_UTENTE 80 50
BEGIN
PROMPT 2 18 ""
FIELD PERCORSO
CHECKTYPE REQUIRED
END
TEXT F_TESTO_TIPOBIL
BEGIN
PROMPT 55 17 "Tipo bilancio"
END
STRING F_TIPO_BILANCIO 2 2
BEGIN
PROMPT 60 18 ""
FLAG "DRU"
KEY 1
USE %NTB KEY 1
INPUT %NTB->CODTAB F_TIPO_BILANCIO
DISPLAY "Cod@5" %NTB->CODTAB
DISPLAY "Descrizione@40" %NTB->S0
OUTPUT F_TIPO_BILANCIO %NTB->CODTAB
CHECKTYPE REQUIRED
END
GROUPBOX DLG_NULL 76 10
BEGIN
PROMPT 1 7 ""
FLAGS "R"
END
BOOLEAN F_PIANO_CONTI
BEGIN
PROMPT 2 9 "Piano dei conti"
FLAG "D"
GROUP 1
END
BOOLEAN F_PERIODI_BILANCI
BEGIN
PROMPT 2 11 "Tabella periodi di bilanci"
FLAG "D"
GROUP 1
END
BOOLEAN F_ANALISI
BEGIN
PROMPT 2 13 "Tabella analisi di bilancio"
FLAG "D"
GROUP 1
END
BOOLEAN F_MOVIMENTI
BEGIN
PROMPT 2 15 "Movimenti"
MESSAGE TRUE ENABLE,F_TIPO_BILANCIO | COPY, F_SALDI
FLAG "D"
GROUP 1
END
BOOLEAN F_SALDI
BEGIN
PROMPT 40 9 "Saldi"
MESSAGE TRUE ENABLE,F_TIPO_BILANCIO
MESSAGE FALSE COPY, F_MOVIMENTI | DISABLE, F_TIPO_BILANCIO
FLAG "D"
GROUP 1
END
BOOLEAN F_VOCI
BEGIN
PROMPT 40 11 "Voci"
MESSAGE TRUE COPY, F_RELAZ | COPY, F_SRELAZ
MESSAGE FALSE COPY, F_RELAZ | COPY, F_SRELAZ
GROUP 1
END
BOOLEAN F_RELAZ
BEGIN
PROMTP 40 13 "Relazioni"
MESSAGE TRUE COPY, F_VOCI | COPY, F_SRELAZ
MESSAGE FALSE COPY, F_VOCI | COPY, F_SRELAZ
GROUP 1
END
BOOLEAN F_SRELAZ
BEGIN
PROMPT 40 15 "Sottorelazioni"
MESSAGE TRUE COPY, F_RELAZ | COPY, F_VOCI
MESSAGE FALSE COPY, F_RELAZ | COPY, F_VOCI
GROUP 1
END
ENDPAGE
ENDMASK

200
src/R_10_00/ab/ab2100b.ini Executable file
View File

@ -0,0 +1,200 @@
[MAIN]
DECSEP =
FIELDSEP = |
RECORDSEP =
RECORDSIZE = 0
TYPEFIELD = 0
[RECORD PIACO]
USE = 78
FIELD(1) = CODCBL
FIELD(2) = DESCRIZ
ALIGN(2) = L
FIELD(3) = INDBIL
FIELD(4) = CODCONTR
FIELD(5) = SOSPESO
[RECORD NTBBB]
USE = %NTB
FIELD(1) = COD
FIELD(2) = CODTAB
ALING(2) = L
FIELD(3) = S0
ALIGN(3) = L
[RECORD TBBBD]
USE = %PDB
FIELD(1) = COD
FIELD(2) = CODTAB
ALIGN(2) = L
FIELD(3) = S0
ALIGN(3) = L
FIELD(4) = I0
FIELD(5) = I1
FIELD(6) = I2
FIELD(7) = I3
[RECORD SALDI]
USE = 79
FIELD(1) = CODDITTA
FIELD(2) = ANNO
FIELD(3) = CODPDB
FIELD(4) = TIPOBIL
FIELD(5) = CODCBL
FIELD(6) = FLDA
FIELD(7) = SALDO
FIELD(8) = PDARE
FIELD(9) = PAVERE
FIELD(10) = RDARE
FIELD(11) = RAVERE
FIELD(12) = IDMOVDETT
ALIGN(12) = L
[RECORD ANALI]
USE = 82
FIELD(1) = CODAN
FIELD(2) = DESCRIZ
ALIGN(2) = L
FIELD(3) = TIPOAN
FIELD(4) = PFSTAL
FIELD(5) = PFSTRF
FIELD(6) = NOTE
[RECORD CARAD]
USE = 126
FIELD(1) = ID
FIELD(2) = STD
FIELD(3) = CLI
FIELD(4) = SPI
FIELD(5) = STI
FIELD(6) = DST
ALING(6) = L
FIELD(7) = CLT
FIELD(8) = SPT
FIELD(9) = STT
FIELD(10) = SVT
FIELD(11) = LST
FIELD(12) = ODA
FIELD(13) = SKI
FIELD(14) = SKT
FIELD(15) = NDV
FIELD(16) = RII
FIELD(17) = RIT
FIELD(18) = TVL
[RECORD COLLD]
USE = 127
FIELD(1) = ID
FIELD(2) = F4A
FIELD(3) = F4B
FIELD(4) = P4A
FIELD(5) = P4B
FIELD(6) = A5A
FIELD(7) = A5B
FIELD(8) = P5A
FIELD(9) = P5B
FIELD(10) = A6A
FIELD(11) = A6B
FIELD(12) = X4A
FIELD(13) = X4B
FIELD(14) = X5A
FIELD(15) = X5B
FIELD(16) = X6A
FIELD(17) = X6B
FIELD(18) = P6A
FIELD(19) = P6B
FIELD(20) = K4A
FIELD(21) = K5A
FIELD(22) = K6A
[RECORD MOVDE]
USE = 80
FIELD(1) = CODDITTA
FIELD(2) = ANNO
FIELD(3) = CODPDB
FIELD(4) = TIPOBIL
FIELD(5) = CODCBL
FIELD(6) = ID
FIELD(7) = TIPODETT
FIELD(8) = CODDETT
ALING(8) = L
FIELD(9) = DESCRIZ
ALIGN(9) = L
FIELD(10) = FLDA
FIELD(11) = IMPORTO
FIELD(12) = PDARE
FIELD(13) = PAVERE
FIELD(14) = RDARE
FIELD(15) = RAVERE
FIELD(16) = DATAREG
FIELD(17) = ANR
FIELD(18) = DATADOC
FIELD(19) = NDOC
FIELD(20) = CAUS
FIELD(21) = IMMESSO
FIELD(22) = DETT
FIELD(23) = INDIR
FIELD(24) = LOC
FIELD(25) = PROV
FIELD(26) = CAP
FIELD(27) = COFI
FIELD(28) = STATOPAIV
FIELD(29) = PAIV
FIELD(30) = IDPADRE
FIELD(31) = IDFIGLIO
FIELD(32) = IDSUCC
FIELD(33) = IDPREC
[RECORD RELNA]
USE = 85
FIELD(1) = CODAN
FIELD(2) = ID
FIELD(3) = IDPADRE
FIELD(4) = IDFIGLIO
FIELD(5) = IDPREC
FIELD(6) = IDSUCC
FIELD(7) = TIPOCOD
FIELD(8) = CODVC
ALING(8) = R
LENGTH(8)= 10
FIELD(9) = IDCOMP
FIELD(10) = DESCRIZ
ALIGN(10) = L
FIELD(11) = IDCARADD
FIELD(12) = USACARADD
FIELD(13) = IDCOLDICH
FIELD(14) = VOCEINCID
[RECORD RELVC]
USE = 84
FIELD(1) = TIPOCOD
FIELD(2) = CODVC
FIELD(3) = IDCOMP
FIELD(4) = NEXTCOMP
FIELD(5) = PREVCOMP
FIELD(6) = COMP
ALING(6) = L
[RECORD TVOCI]
USE = 83
FIELD(1) = CODVC
FIELD(2) = DESCRIZ
ALING(2) = L
FIELD(3) = TIPOVC
FIELD(4) = CODCBL
FIELD(5) = INDBIL
FIELD(6) = IDCARADD
FIELD(7) = TVL
FIELD(8) = CLASSEVOCE

1197
src/R_10_00/ab/ab2101.cpp Executable file

File diff suppressed because it is too large Load Diff

504
src/R_10_00/ab/ab2102.cpp Executable file
View File

@ -0,0 +1,504 @@
//AB2102.CPP Trasferimento tabelle
#include <utility.h> //Definizione di fexit
#include "movdett.h" //Contiene le definizioni di costanti relative ai nomi dei campi di LF_MOVDETT
#include "saldi.h" //Contiene le definizioni di costanti relative ai nomi dei campi di LF_SALDI
#include "relana.h" //Contiene le definizioni di costanti relative ai nomi dei campi di LF_RELANA
#include "ab2100.h"
#include "ab2100a.h"
#include <progind.h>
#include <assoc.h>
#include <varrec.h>
#define TABELLA_TIPO_BILANCI "NTBBB"
const char* get_ordinamento(TVariable_rectype & rec)
{
if (rec.get(ABMD_TIPODETT) == FLAG_DETT_DT || rec.get(ABMD_TIPODETT) == FLAG_COGE_CG )
{ //E' un record di MOVI3
return (MOVIMENTO3);
}
if (rec.get(ABMD_TIPODETT) == FLAG_CLIENTE_CL)
{//E' un record di MOVI4
return (MOVIMENTO4);
}
if (rec.get(ABMD_TIPODETT) == FLAG_FORNITORE_FO)
{//E' un record di MOVI5
return (MOVIMENTO5);
}
if (rec.get(ABMD_TIPODETT) == FLAG_MOVIMENTO_MO)
{//Può essere MOVI 1 2
real r(rec.get(ABMD_IMPORTO));
if (r > 0)
//Se è un saldo il record va in MOVI1
return (MOVIMENTO1);
//Se è un progressivo o una riclassificazione va in MOVI2
return (MOVIMENTO2);
}
//A questo punto la funzione non dovrebbe mai arrivare
CHECK (FALSE,"La funzione get_ordinamento ritorna un valore non valido");
return NULL;
}
bool TInvio_AS400::cerca_padre(TLocalisamfile & padre, TRectype &node)
{
padre.put(ABMD_CODDITTA,node.get(ABMD_CODDITTA));
padre.put(ABMD_ANNO,node.get(ABMD_ANNO));
padre.put(ABMD_CODPDB,node.get(ABMD_CODPDB));
padre.put(ABMD_TIPOBIL,node.get(ABMD_TIPOBIL));
padre.put(ABMD_CODCBL,node.get(ABMD_CODCBL));
padre.put(ABMD_ID,node.get(ABMD_IDPADRE));
if (padre.read() == NOERR)
return TRUE;
return FALSE;
}
long TInvio_AS400::my_num(TLocalisamfile& mov, TAssoc_array& progressivi)
{
long ret = 1;
TToken_string my_key;
my_key.add(mov.get(ABMD_CODDITTA));
my_key.add(mov.get(ABMD_ANNO));
my_key.add(mov.get(ABMD_CODPDB));
my_key.add(mov.get(ABMD_TIPOBIL));
my_key.add(mov.get(ABMD_CODCBL));
my_key.add(mov.get(ABMD_ID));
if (progressivi.is_key(my_key))
{
ret = atol(*(TString*)progressivi.objptr(my_key));
}
else
{
long id_prec =mov.get_long(ABMD_IDPREC);
// if (id_prec != ID_NULLO) // Se il padre di un movimento è nullo significa che è un movimento di un saldo
// {
mov.put(ABMD_ID,id_prec);
if (mov.read()== NOERR)
{
ret=my_num(mov,progressivi)+1;
}
// else
// CHECK (FALSE,"Si è verificata una inconsistenza nei dati: è stato trovato un movimento senza il padre!");
//}
TString16 str_ret;
str_ret << ret;
progressivi.add(my_key,str_ret);
}
return ret;
}
void TInvio_AS400::trasferisci_albero(TRectype &node, TRecord_text &rec, TAssoc_array &progressivi)
{
TLocalisamfile mov(LF_MOVDETT);
//Se è un COGE scrivo il CODICE_COGE nel relativo campo
if (node.get(ABMD_TIPODETT) == FLAG_COGE_CG)
rec.add(node.get(ABMD_CODDETT),CONTO_COGE_MOVDETT);
//Se è un movimento ...
if (node.get(ABMD_TIPODETT)== FLAG_MOVIMENTO_MO)
{ //... sono all'ultimo livello: trovo il padre
if (cerca_padre(mov,node))
{//Questo è il padre del movimento
if (mov.get(ABMD_TIPODETT) == FLAG_COGE_CG) //Se il padre è un COGE scrivo il CONTO COGE nel relativo campo
rec.add(node.get(ABMD_CODDETT),CONTO_COGE_MOVDETT);
//altrimenti, se il padre è un dettaglio, non scrivo nessuna informazione aggiuntiva
}
// Se il padre del movimento non esiste, allora è un movimento di un saldo
// else
// {//Non dovrebbe mai succedere: non esiste il padre del movimento
// CHECK (FALSE,"Si è verificata una inconsistenza nei dati: è stato trovato un movimento senza il padre!");
// }
//Questa parte esegue la "numerazione progressiva" dei movimenti: assegna il numero di riga
TString16 num_riga;
mov.curr()=node;
num_riga << my_num(mov,progressivi);
rec.add(num_riga,NUMERO_RIGA_MOVDETT);
//Trovo il padre se esiste
long id_padre = atol(node.get(ABMD_IDPADRE));
real r(node.get(ABMD_CODDETT));
if ((id_padre != ID_NULLO) && (r == 0)) //Se esiste il padre e non sono un COGE devo assegnarmi
//nel campo PROGRESSIVO_DETT il numero progressivo del padre
{//Leggo il padre
mov.curr()=node;
mov.put(ABMD_ID,id_padre);
if (mov.read()==NOERR)
{
TString16 num_prog;
num_prog << my_num(mov,progressivi);
rec.add(num_prog,PROGRESSIVO_DETT_MOVDETT); //Questo è un record di tipo MOVIMENTI
}
else
CHECK (FALSE,"Si è verificata una inconsistenza nei dati: è stato trovato un movimento senza il padre!");
}
}//Fine parte "ricostruzione" albero dei movimenti
//Questa parte "ricostruisce" l'albero dei dettaglio
if (node.get(ABMD_TIPODETT)== FLAG_DETT_DT)
{
mov.curr()=node;
TString16 num;
num << my_num(mov,progressivi);
rec.add(num,PROGRESSIVO_DETT_MOVDETT); //Questo è un record di tipo DETTAGLI
}
}
bool TInvio_AS400::mov_da_scrivere(TRectype &node)
{
TLocalisamfile dett(LF_MOVDETT);
if (node.get_long(ABMD_IDPADRE) == ID_NULLO) //Sono al primo livello
return TRUE;
if (cerca_padre(dett,node))
{
if (dett.get_long(ABMD_IDPADRE) == ID_NULLO) //Sono al secondo livello
return TRUE;
else
{
if (dett.get(ABMD_TIPODETT) == FLAG_COGE_CG) //Sono al terzo livello, ma ammetto solo i COGE
return TRUE;
}
}
return FALSE; //Tutti i livelli superiori a 2 e tutti i casi che non riesco a gestire
}
void TInvio_AS400::formatta(TRecord_text &rec, TRectype &node, int &logic_num)
{
if (logic_num == LF_MOVDETT)
{
if ((rec.type() == MOVIMENTO1) || (rec.type() == MOVIMENTO2))
{//Se c'è un valore significativo in IMPORTO significa che questo valore va
//inserito nel campo IMPORTO del file di testo e settato il flag D/A
//Il tipo record (già settato) è MOVI1
real r(node.get(ABMD_IMPORTO));
if (r > 0)
{
TString imp = node.get(ABMD_IMPORTO);
rec.add(node.get(ABMD_FLDA),FLAG_DA_MOVDETT);
rec.add(imp.rtrim(4),IMPORTO_MOVDETT);
}
else
{//Questi valori vanno inseriti in IMPORTO di MOVI2
real rpd(node.get(ABMD_PDARE));
real rpa(node.get(ABMD_PAVERE));
real rrd(node.get(ABMD_RDARE));
real rra(node.get(ABMD_RAVERE));
if (rpd > 0)
{
TString imp =node.get(ABMD_PDARE);
rec.add("D",FLAG_DA_MOVDETT);
rec.add(imp.rtrim(4),IMPORTO_MOVDETT);
}
if (rpa > 0)
{
TString imp = node.get(ABMD_PAVERE);
rec.add("A",FLAG_DA_MOVDETT);
rec.add(imp.rtrim(4),IMPORTO_MOVDETT);
}
if (rrd > 0)
{
TString imp = node.get(ABMD_RDARE);
rec.add("X",FLAG_RICLASSIFICAZIONE_MOVDETT);
rec.add("D",FLAG_DA_MOVDETT);
rec.add(imp.rtrim(4),IMPORTO_MOVDETT);
}
if (rra > 0)
{
TString imp = node.get(ABMD_RAVERE);
rec.add("X",FLAG_RICLASSIFICAZIONE_MOVDETT);
rec.add("A",FLAG_DA_MOVDETT);
rec.add(imp.rtrim(4),IMPORTO_MOVDETT);
}
}
}
else
{//Questi sono gli importi dei dettagli
TString sld = rec.row(SALDO_INIZIO_ANNO_MOVDETT);
rec.add(sld.rtrim(4),SALDO_INIZIO_ANNO_MOVDETT);
TString pda = rec.row(PROGRESSIVO_DARE_MOVDETT);
rec.add(pda.rtrim(4),PROGRESSIVO_DARE_MOVDETT);
TString pav = rec.row(PROGRESSIVO_AVERE_MOVDETT);
rec.add(pav.rtrim(4),PROGRESSIVO_AVERE_MOVDETT);
TString rda = rec.row(RICLASSIFICAZIONE_DARE_MOVDETT);
rec.add(rda.rtrim(4),RICLASSIFICAZIONE_DARE_MOVDETT);
TString rav = rec.row(RICLASSIFICAZIONE_AVERE_MOVDETT);
rec.add(rav.rtrim(4),RICLASSIFICAZIONE_AVERE_MOVDETT);
}
}// end if LF_MOVDETT
if (logic_num == LF_ABSALDI)
{
TString sld = rec.row(SALDO_INIZIO_ANNO_SLD_MOVDETT);
rec.add(sld.rtrim(4),SALDO_INIZIO_ANNO_SLD_MOVDETT);
TString pda = rec.row(PROGRESSIVO_DARE_SLD_MOVDETT);
rec.add(pda.rtrim(4),PROGRESSIVO_DARE_SLD_MOVDETT);
TString pav = rec.row(PROGRESSIVO_AVERE_SLD_MOVDETT);
rec.add(pav.rtrim(4),PROGRESSIVO_AVERE_SLD_MOVDETT);
TString rda = rec.row(RICLASSIFICAZIONE_DARE_SLD_MOVDETT);
rec.add(rda.rtrim(4),RICLASSIFICAZIONE_DARE_SLD_MOVDETT);
TString rav = rec.row(RICLASSIFICAZIONE_AVERE_SLD_MOVDETT);
rec.add(rav.rtrim(4),RICLASSIFICAZIONE_AVERE_SLD_MOVDETT);
}// end if LF_ABSALDI
if (logic_num == LF_TABCOM && rec.type() == TIPO_TABELLA_PERIODI)
{
rec.add(SIGLA_TABELLA_PERIODI,SIGLA_TAB_PER);
}
}
void TObject_send::converti(int logic_num)
{
TRelation *tr_relation=_trasfile->t_rec(logic_num)->relation();
TRecord_text rec(_trasfile->t_rec(logic_num)->type()); //Istanzio un tipo record_text
TCursor *cur=NULL;
cur = new TCursor(tr_relation);
//Leggo il numero di records da convertire
long items =cur->items();
//Barra scorrevole di attesa
TProgind idle(items,TR("Attendere: conversione in corso ..."),TRUE,TRUE,60);
//Ciclo principale di conversione
for (*cur=0;cur->pos()<items;++*cur)
{
idle.addstatus(1);
_trasfile->autoload(rec,logic_num);
rec.add(rec.type(),0);
_trasfile->write(rec);
}
delete cur;
}
void TObject_send::converti(int main_file, const char * tabname)
{
TRelation *tr_relation=_trasfile->t_rec(main_file,tabname)->relation();
TRecord_text rec(_trasfile->t_rec(main_file,tabname)->type()); //Istanzio un tipo record_text
TCursor *cur=NULL;
cur = new TCursor(tr_relation);
// int logic_num= tr_relation->lfile().num();
//Leggo il numero di records da convertire
long items =cur->items();
//Barra scorrevole di attesa
TProgind idle(items,TR("Attendere: conversione in corso ..."),TRUE,TRUE,60);
//Ciclo principale di conversione
for (*cur=0;cur->pos()<items;++*cur)
{
idle.addstatus(1);
// _trasfile->autoload(rec,logic_num);
_trasfile->autoload(rec,tabname);
rec.add(rec.type(),0);
_trasfile->write(rec);
}
delete cur;
}
void TInvio_AS400::converti(int logic_num)
{
TRelation *tr_relation=trans_file()->t_rec(logic_num)->relation();
TRecord_text rec(trans_file()->t_rec(logic_num)->type()); //Istanzio un tipo record_text
TCursor *cur=NULL;
TAssoc_array progressivi;
if (logic_num == LF_MOVDETT)
{
TVariable_rectype *vrec_rmov= new TVariable_rectype(LF_MOVDETT);
vrec_rmov->add_field(new TVariable_field (ABMD_TIPO_TRACCIATO,get_ordinamento,5));
//Costruisco la chiave del TSorted_cursor
TToken_string exp(ABMD_TIPO_TRACCIATO);
exp.add(ABMD_CODDITTA);
exp.add(ABMD_ANNO);
exp.add(ABMD_CODPDB);
exp.add(ABMD_TIPOBIL);
exp.add(ABMD_CODCBL);
exp.add(ABMD_ID);
cur = new TSorted_cursor(tr_relation,exp);
cur->file().set_curr(vrec_rmov);
}
else
cur = new TCursor(tr_relation);
//Leggo il numero di records da convertire
long items =cur->items();
//Barra scorrevole di attesa
TProgind idle(items,TR("Attendere: conversione in corso ..."),TRUE,TRUE,60);
//Ciclo principale di conversione
for (*cur=0;cur->pos()<items;++*cur)
{
idle.addstatus(1);
if (logic_num == LF_MOVDETT)
{//In questo caso la conversione è un po' particolare
rec.set_type(tr_relation->lfile().get(ABMD_TIPO_TRACCIATO));
trans_file()->autoload(rec,*cur,&rec.type());
if (mov_da_scrivere(tr_relation->lfile().curr()))
{
trasferisci_albero(tr_relation->lfile().curr(),rec,progressivi);
formatta(rec,tr_relation->lfile().curr(),logic_num);
trans_file()->write(rec);
}
}
else
{//in tutti gli altri casi la conversione è semplice
trans_file()->autoload(rec,logic_num);
if (logic_num == LF_ABSALDI || logic_num == LF_TABCOM)
formatta(rec,tr_relation->lfile().curr(),logic_num);
trans_file()->write(rec);
}
}
delete cur;
}
//Handler per l'inserimento del percorso completo
bool TInvio::inseriscipercorso(TMask_field& f, KEY k)
{
TString percorso;
percorso=f.get(); //Leggo il contenuto del campo
return TRUE;
}
//Funzione membro che esegue la conversione di trasferimento
//bool TInvio_AS400::menu(MENU_TAG)
void TInvio::main_loop()
{
TMask msk("AB2100A"); //Maschera dove si chiede di immettere il percorso del file sorgente
TFilename percorso; //Contiene il percorso completo del file sorgente
msk.set_handler(F_PERCORSO, inseriscipercorso); //Assegno un handler al campo F_PERCORSO
//inseriscipercorso controlla che il percorso (e il file) esista e sia corretto
msk.set_handler(F_PERCORSO_UTENTE, inseriscipercorso);
msk.hide(F_TIPO_BILANCIO); //nascondo questo campo poichè non mi serve
msk.hide(F_TESTO_TIPOBIL); //nascondo questo campo poichè non mi serve
msk.enable(-1,TRUE);
if (msk.run()== K_ENTER) //Eseguo la maschera
{
//A questo punto il percorso e' corretto
percorso=msk.get(F_PERCORSO); //Leggo il contenuto di F_PERCORSO
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_AS400)
{
if ((msk.get_bool(F_VOCI) == TRUE) ||
(msk.get_bool(F_RELAZ) == TRUE) ||
(msk.get_bool(F_SRELAZ) == TRUE))
{
message_box(TR("L'invio a AS400 delle VOCI, RELAZIONI e SOTTORELAZIONI non è attualmente previsto"));
}
_invio = new TInvio_AS400(percorso);
}
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_INTERNA)
{
_invio = new TObject_send(percorso);
}
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_USER_DEFINED)
{
TString config_file(msk.get(F_PERCORSO_UTENTE)); //Nome del file di configurazione
_invio = new TInvio_user_defined(config_file,percorso);
}
// Parte di invio
if (msk.get_bool(F_PIANO_CONTI)==TRUE) //Controllo se si è scelto di convertire il piano dei conti
{
_invio->converti(LF_ABPCON); //Conversione
}
if (msk.get_bool(F_PERIODI_BILANCI)==TRUE) //Scelta di convertire la tabella periodi bilanci
{
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_AS400)
{//Se eseguo un invio a AS400 converto passando il numero del file
_invio->converti(LF_TABCOM);
}
else
{ //Se eseguo un invio interno converto passando il nome della tabella comune
_invio->converti(LF_TABCOM,"%PDB");
_invio->converti(LF_TABCOM,"%NTB");
}
}
if (msk.get_bool(F_ANALISI)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio
{
_invio->converti(LF_ANALISI);
}
if (msk.get_bool(F_MOVIMENTI)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio
{
_invio->converti(LF_MOVDETT);
}
if (msk.get_bool(F_SALDI)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio
{
_invio->converti(LF_ABSALDI);
}
if (msk.get_int(F_TIPO_RICE) != RICEZIONE_AS400)
{// Solo se non è un invio ad AS400
if (msk.get_bool(F_VOCI)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio
{
_invio->converti(LF_VOCI);
}
if (msk.get_bool(F_RELAZ)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio
{
_invio->converti(LF_RELVOCI);
}
if (msk.get_bool(F_SRELAZ)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio
{
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_INTERNA)
{
_invio->converti(LF_CARADD);
_invio->converti(LF_COLLDICH);
}
_invio->converti(LF_RELANA);
}
}
delete _invio;
//messaggio finale
message_box(" ... aggiornamento delle tabelle effettuato");
} //end if (msk.run())
// return FALSE;
}
int ab2102(int argc, char **argv)
{
TInvio a;
a.run(argc,argv,TR("Trasferimento su file di testo"));
return 0;
}
TObject_send::TObject_send(const TFilename &percorso)
{
if (_trasfile != NULL)
delete _trasfile;
_trasfile = new TFile_text(percorso, "ab2100b.ini"); /*DA CAMBIARE*/
_trasfile->open('w'); //apro il TFile_text in lettura
}
TInvio_AS400::TInvio_AS400(const TFilename &percorso)
{
if (_trasfile != NULL)
delete _trasfile;
_trasfile = new TFile_text(percorso, "ab2100a.ini"); /*DA CAMBIARE*/
_trasfile->open('w'); //apro il TFile_text in lettura
}
TInvio_user_defined::TInvio_user_defined(const TString & config, const TFilename &percorso)
{
if (_trasfile != NULL)
delete _trasfile;
_trasfile = new TFile_text(percorso, config); //Leggo il file di configurazione
_trasfile->open('w'); //apro il TFile_text in lettura
}

11
src/R_10_00/ab/ab3.cpp Executable file
View File

@ -0,0 +1,11 @@
#include <xvt.h>
#include <checks.h>
#include "ab3.h"
int main(int argc,char **argv)
{
ab3100(argc,argv);
exit(0);
return 0;
}

6
src/R_10_00/ab/ab3.h Executable file
View File

@ -0,0 +1,6 @@
#ifndef __AB3_H
#define __AB3_H
void ab3100(int argc, char **argv);
#endif //__AB3_H

349
src/R_10_00/ab/ab3100.cpp Executable file
View File

@ -0,0 +1,349 @@
#include <treectrl.h>
#include "ab3100.h"
inline TGestione_tree &app() { return (TGestione_tree &)main_app();}
bool gestione_sheet(TSheet_field& s, int r, KEY k)
{
if (k == K_CTRL + K_INS)
{
TRelation *rel = app().get_relation();
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
TToken_string &codice = s.row(r-1);
ab_tree.insert_new_node(codice);
ab_tree.user_tree()->write_cache(); //solo debug
ab_tree.user_tree_voc()->write_cache(); //solo debug
// Sincronizzo l'albero con lo sheet
ab_tree.user_tree()->goto_father();
naviga_tree(s.mask().field(F_TREE),K_SPACE);
TMask &s_msk = s.sheet_mask();
s_msk.field(F_COMPONENTE).on_key(K_F9);
const TString &componente = s_msk.get(F_COMPONENTE);
s.row(r).add(componente,F_COMPONENTE-F_ID);
k = K_ENTER;
}
if (k == K_DEL)
{
TRelation *rel = app().get_relation();
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
TToken_string &codice = s.row(r);
//Posiziono il nodo sul record selezionato
TNumeric_id temp_id = codice.get(0);
ab_tree.remove_node(temp_id);
ab_tree.user_tree()->goto_father();
}
/* if ( k = K_CTRL + K_DEL)
{
// Sincronizzo l'albero con lo sheet come risposta alla rimozione
naviga_tree(s.mask().field(F_TREE),K_SPACE);
} */
if (k == K_ENTER)
{
TRelation *rel = app().get_relation();
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
TMask& msk = s.sheet_mask();
// A questo punto devo modificare il contenuto di CARADD:
// ricavo il suo contenuto da maschera, e lo scrivo nella cache
// se il nodo è stato rimosso, la caradd non viene rimossa dal database: per
// rimuoverla fare i passi successivi in K_DEL
TRectype caradd(ricava_caradd(msk));
ab_tree.user_caradd()->current_cache_record().put(caradd);
ab_tree.user_caradd()->set_status_node(caradd.get(ABCA_ID),NODO_MODIFICATO);
ab_tree.user_caradd()->write_cache(); //solo debug
// TRectype coll(ricava_colldich(msk));
// ab_tree.user_colldich()->current_cache_record().put(coll);
// ab_tree.user_colldich()->set_status_node(coll.get(ABCD_ID),NODO_MODIFICATO);
// ab_tree.user_colldich()->write_cache(); //solo debug
TToken_string &codice = s.row(r);
ab_tree.modify_node(codice);
// Sincronizzo l'albero con lo sheet
ab_tree.user_tree()->goto_father();
naviga_tree(s.mask().field(F_TREE),K_SPACE);
}
return TRUE;
}
bool naviga_tree(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{ //Premuto su un nodo
TTree_field &tf = (TTree_field&)f; //Trasformo il contenuto del campo in un tree
TMask &_msk=f.mask(); //Prelevo la maschera
TSheet_field &sheet_box = _msk.sfield(F_VISTA); //Creo un array che conterrà i dati dello sheet
sheet_box.destroy(-1,FALSE); // ... e lo vuoto
TLocalisamfile voci(LF_VOCI);
TAlbero_locale *ab = (TAlbero_locale*)tf.tree();
TRelation *rel = app().get_relation();
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
TToken_string key_rel;
TString father_id;
ab->curr_id(father_id); //Salvo l'id del padre
TNumeric_id temp_id; // Serve per la navigazione dei figli
temp_id = ab->current().get_real(ABRA_IDFIGLIO);
if (temp_id > ID_NULLO)
{ // Significa che ho dei figli
for (int i = 0; temp_id > ID_NULLO; i++ )
{
TToken_string &codice = sheet_box.row(i); //Setto la riga dell sheet
ab->goto_node(temp_id); //vado sul nodo
ab->curr_id(codice);
codice.add(ab->current().get(ABRA_TIPOCOD));
codice.add(ab->current().get(ABRA_CODVC));
codice.add(ab->current().get(ABRA_NCOMP));
codice.add(ab->current().get(ABRA_VOCEINCID));
codice.add(ab->current().get(ABRA_DESCRIZ));
codice.add(ab->current().get(ABRA_USACARADD));
// Rintraccio i dati di RELVOCI
key_rel.cut(0);
key_rel.add(ab->current().get(ABRA_TIPOCOD));
key_rel.add(ab->current().get(ABRA_CODVC));
key_rel.add(ab->current().get(ABRA_NCOMP));
ab_tree.user_tree_voc()->goto_node(key_rel);
// Rintraccio i dati di VOCI
voci.put(ABVC_CODVC,ab_tree.user_tree_voc()->current().get(ABRL_CODCOMP));
if (voci.read() == NOERR)
{
codice.add(voci.get(ABVC_CODVC));
if ( ab->current().get_bool(ABRA_USACARADD) )
{ // Se il nodo esisteva già, ci sarà anche la caradd;
// se il nodo è nuovo, la caradd la devo aggiungere
TNumeric_id id_caradd(ab->current().get(ABRA_IDCARADD)); // Caratteristica addizionale ridefinita
if (id_caradd != ID_NULLO)
{ // Esiste già una caradd specifica definita
codice.add(id_caradd.string());
}
else
{ // Devo trovare un nuovo id per la nuova caradd
id_caradd = ab_tree.new_id_caradd();
codice.add(id_caradd.string());
}
}
else
{ // Uso la caradd di default
codice.add(voci.get(ABVC_IDCARADD)); // Caratteristiche addizionali di default
}
// sheet_box.disable_cell(i,7);
// sheet_box.disable_cell(i,8);
}
else
{
;
}
sheet_box.check_row(i);
temp_id = ab->current().get_real(ABRA_IDSUCC);
} // Ho finito di scorrere (e visualizzare) tutti i figli
//Riposiziono il nodo e aggiorno lo sheet
ab->goto_node(father_id);
sheet_box.force_update();
}
else
{
sheet_box.destroy(-1,FALSE);
}
return TRUE;
}
return TRUE;
}
TRectype ricava_colldich(TMask & msk)
{
TRectype coll (LF_COLLDICH);
TString id = msk.get(F_ID_COLL);
// FARE LA SERIE DI PUT COME NELLA RICAVA CARADD
return coll;
}
// Guy says: bendate il programmatore, caricat, puntat, fuoco!
TRectype ricava_caradd(TMask & msk)
{
TRectype car (LF_CARADD);
TString id = msk.get(F_IDCARADD);
car.put(ABCA_ID,id.right_just(12,' '));
car.put(ABCA_STD,msk.get(F_STAMPA_DETT));
car.put(ABCA_CLI,msk.get(F_COL_STM_IMP));
car.put(ABCA_SPI,msk.get(F_CAR_SOPRA));
car.put(ABCA_STI,msk.get(F_CAR_SOTTO));
car.put(ABCA_DST,msk.get(F_DESCR_TOT));
car.put(ABCA_CLT,msk.get(F_COL_STM_TOT));
car.put(ABCA_SPT,msk.get(F_CAR_SOPRA_TOT));
car.put(ABCA_STT,msk.get(F_CAR_SOTTO_TOT));
car.put(ABCA_SVT,msk.get(F_STAMPA_IMP_TOT));
car.put(ABCA_LST,msk.get(F_LIV_STR));
car.put(ABCA_ODA,msk.get(F_FLAG_DA));
car.put(ABCA_SKI,msk.get(F_LINEA_SALTA_SMP));
car.put(ABCA_SKT,msk.get(F_LINEA_SALTA_TOT));
car.put(ABCA_NDV,msk.get(F_NON_DSR_VOC_COM));
car.put(ABCA_RII,msk.get(F_RIGA_GRASS));
car.put(ABCA_RIT,msk.get(F_RIGA_TOT_VC_CMP));
car.put(ABCA_TVL,msk.get(F_TVL));
return car;
}
void aggiorna_colldich(TMask &msk)
{
TLocalisamfile coll(LF_COLLDICH);
coll.put(ABCD_ID,msk.get(F_ID_COLL));
if (coll.read() != NOERR)
{
coll.curr().zero();
}
// FARE LA SERIE DI SET DAI CAMPI DELLA MASCHERA COME NELLA AGGIORNA_CARADD
}
void aggiorna_caradd(TMask &msk)
{
TLocalisamfile car(LF_CARADD);
car.put(ABCA_ID,msk.get(F_IDCARADD));
if (car.read() != NOERR)
{
car.curr().zero();
}
msk.set(F_STAMPA_DETT,car.get(ABCA_STD));
msk.set(F_COL_STM_IMP,car.get(ABCA_CLI));
msk.set(F_CAR_SOPRA,car.get(ABCA_SPI));
msk.set(F_CAR_SOTTO,car.get(ABCA_STI));
msk.set(F_DESCR_TOT,car.get(ABCA_DST));
msk.set(F_COL_STM_TOT,car.get(ABCA_CLT));
msk.set(F_CAR_SOPRA_TOT,car.get(ABCA_SPT));
msk.set(F_CAR_SOTTO_TOT,car.get(ABCA_STT));
msk.set(F_STAMPA_IMP_TOT,car.get(ABCA_SVT));
msk.set(F_LIV_STR,car.get(ABCA_LST));
msk.set(F_FLAG_DA,car.get(ABCA_ODA));
msk.set(F_LINEA_SALTA_SMP,car.get(ABCA_SKI));
msk.set(F_LINEA_SALTA_TOT,car.get(ABCA_SKT));
msk.set(F_NON_DSR_VOC_COM,car.get(ABCA_NDV));
msk.set(F_RIGA_GRASS,car.get(ABCA_RII));
msk.set(F_RIGA_TOT_VC_CMP,car.get(ABCA_RIT));
msk.set(F_TVL,car.get(ABCA_TVL));
}
bool aggiorna_id_colldich(TMask_field& f, KEY k)
{
if ((k==K_SPACE) && (f.dlg() == F_USA_COLL) && (f.focusdirty()))
{
TRelation *rel = app().get_relation();
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
TMask &sheet_msk = f.mask();
if (sheet_msk.get_bool(F_USA_COLL))
{
ab_tree.user_tree()->goto_node(sheet_msk.get(F_ID));
TNumeric_id id_coll(ab_tree.user_tree()->current().get(ABRA_IDCOLDICH)); // id del collegamento a dich.
if (id_coll != ID_NULLO)
{
//Rintraccio il collegamento
sheet_msk.set(F_ID_COLL,id_coll);
}
else
{
//Devo reperire un id disponibile
id_coll = ab_tree.new_id_colldich();
sheet_msk.set(F_ID_COLL,id_coll);
}
// Aggiorno la maschera dei collegamenti a dich.
aggiorna_colldich(sheet_msk);
return TRUE;
}
}
return TRUE;
}
bool aggiorna_id_caradd(TMask_field& f, KEY k)
{
if (((k==K_TAB) && (f.focusdirty()) && (f.dlg()==F_COMPONENTE))
|| ((k==K_SPACE) && (f.dlg() == F_USA_CARADD) && (f.focusdirty())))
{
TRelation *rel = app().get_relation();
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
TMask &sheet_msk = f.mask();
if (sheet_msk.get_bool(F_USA_CARADD))
{ //CARADD NON DI DEFAULT
ab_tree.user_tree()->goto_node(sheet_msk.get(F_ID));
TNumeric_id id_caradd(ab_tree.user_tree()->current().get(ABRA_IDCARADD)); // Caratteristica addizionale ridefinita
if (id_caradd != ID_NULLO)
{ // Esiste già una caradd specifica definita
sheet_msk.set(F_IDCARADD,id_caradd);
}
else
{ // Devo trovare un nuovo id per la nuova caradd
id_caradd = ab_tree.new_id_caradd();
sheet_msk.set(F_IDCARADD,id_caradd);
}
}
else
{ //CARADD DI DEFAULT
TLocalisamfile voci(LF_VOCI);
// Rintraccio i dati di VOCI
voci.put(ABVC_CODVC,sheet_msk.get(F_COMPONENTE));
if (voci.read() == NOERR)
{
sheet_msk.set(F_IDCARADD,voci.get(ABVC_IDCARADD));
}
else
{
error_box (TR("Voce non presente nell'archivio voci"));
}
}
aggiorna_caradd(sheet_msk);
return TRUE;
}
return TRUE;
}
bool TGestione_tree::user_create()
{
_msk = new TMask("ab3100a");
_anas = new TRelation(LF_ANALISI);
TAnalisi_bil *tree = new TAnalisi_bil();
_anas->lfile().set_curr(tree);
TTree_field & tf = (TTree_field&)_msk->field(F_TREE);
tf.set_tree(tree->user_tree());
tf.hide_leaves(); //Nasconde le foglie dell'albero
TSheet_field &sheet = _msk->sfield(F_VISTA); //Creo un array che conterrà i dati dello sheet
_msk->set_handler(F_TREE, naviga_tree);
sheet.set_append(FALSE);
sheet.sheet_mask().set_handler(F_COMPONENTE,aggiorna_id_caradd);
sheet.sheet_mask().set_handler(F_USA_CARADD,aggiorna_id_caradd);
sheet.sheet_mask().set_handler(F_USA_COLL,aggiorna_id_colldich);
sheet.set_notify(gestione_sheet);
return TRUE;
}
bool TGestione_tree::user_destroy()
{
delete _anas;
delete _msk;
return FALSE;
}
void ab3100(int argc, char **argv)
{
TGestione_tree a;
a.run(argc,argv, TR("Gestione dati"));
}

36
src/R_10_00/ab/ab3100.h Executable file
View File

@ -0,0 +1,36 @@
#include <msksheet.h>
#include "ab3.h"
#include "ablib01.h"
#include "ab3100a.h"
#include "ablib09.h"
//Serve per eseguire il test
class TGestione_tree: public TRelation_application
{
TMask* _msk;
TRelation* _anas;
protected:
virtual bool user_create();
virtual bool user_destroy();
virtual bool changing_mask(int mode) {return false;}
// void gestione_analisi();
// void gestione_saldi();
public:
virtual TMask* get_mask(int mode) {return _msk;}
virtual TRelation* get_relation() const {return _anas;}
};
bool gestione_sheet(TSheet_field& s, int r, KEY k);
bool naviga_tree(TMask_field& f, KEY k);
bool aggiorna_id_caradd(TMask_field& f, KEY k);
void aggiorna_caradd(TMask &msk);
TRectype ricava_caradd(TMask & msk);
bool aggiorna_id_caradd(TMask_field& f, KEY k);
void aggiorna_colldich(TMask &msk);
TRectype ricava_colldich(TMask & msk);

82
src/R_10_00/ab/ab3100a.h Executable file
View File

@ -0,0 +1,82 @@
#ifndef _AB3100A_H
#define _AB3100A_H
#define F_ID 101
#define F_TIPO 102
#define F_CODICE 103
#define F_COMP 104
#define F_VOCE_INC 105
#define F_DESCR 106
#define F_USA_CARADD 107
#define F_COMPONENTE 108
#define F_IDCARADD 109
#define F_ID_COLL 110
#define F_USA_COLL 111
#define F_TESTO_GENERALE 150
#define F_TESTO_CARADD 151
#define F_TESTO_COLLDICH 152
#define F_STAMPA_DETT 153
#define F_STAMPA_IMP_TOT 154
#define F_NON_DSR_VOC_COM 155
#define F_RIGA_GRASS 156
#define F_RIGA_TOT_VC_CMP 157
#define F_TVL 158
#define F_COL_STM_IMP 160
#define F_COL_STM_TOT 161
#define F_CAR_SOPRA 162
#define F_CAR_SOTTO 163
#define F_CAR_SOPRA_TOT 164
#define F_CAR_SOTTO_TOT 165
#define F_LIV_STR 170
#define F_FLAG_DA 171
#define F_LINEA_SALTA_SMP 172
#define F_LINEA_SALTA_TOT 173
#define F_DESCR_TOT 174
#define F_F4A 351
#define F_F4B 352
#define F_P4A 353
#define F_P4B 354
#define F_A5A 355
#define F_A5B 356
#define F_P5A 357
#define F_P5B 358
#define F_A6A 360
#define F_A6B 361
#define F_X4A 362
#define F_X4B 363
#define F_X5A 364
#define F_X5B 365
#define F_X6A 366
#define F_X6B 367
#define F_P6A 368
#define F_P6B 369
#define F_K4A 370
#define F_K5A 371
#define F_K6A 372
#define F_TREE 250
#define F_VISTA 251
#define F_CODICE_ANALISI 252
#define F_DESCRIZIONE_ANALISI 253
#endif //_AB3100A_H

403
src/R_10_00/ab/ab3100a.uml Executable file
View File

@ -0,0 +1,403 @@
#include "ab3100a.h"
TOOLBAR "topbar" 0 0 0 2
#include <relapbar.h>
ENDPAGE
PAGE "Tabella di analisi" 0 -1 0 19
STRING F_CODICE_ANALISI 2 2
BEGIN
PROMPT 1 3 "Codice: "
USE LF_ANALISI KEY 1
INPUT CODAN F_CODICE_ANALISI
DISPLAY "Codice" CODAN
DISPLAY "Descrizione@50" DESCRIZ
OUTPUT F_CODICE_ANALISI CODAN
OUTPUT F_DESCRIZIONE_ANALISI DESCRIZ
FIELD CODAN
CHECKTYPE REQUIRED
KEY 1
FLAGS "U"
END
STRING F_DESCRIZIONE_ANALISI 80 60
BEGIN
PROMPT 1 5 "Descrizione: "
FIELD DESCRIZ
CHECKTYPE NORMAL
KEY 2
FLAGS "U"
END
ENDPAGE
PAGE "Gestione dati" 0 -1 0 19
TREE F_TREE 0 6
BEGIN
PROMPT 0 1 ""
END
SPREADSHEET F_VISTA 0 9
BEGIN
PROMPT 0 10 ""
ITEM "Id@9"
ITEM "Tipo"
ITEM "Codice voce@12"
ITEM "Comp"
ITEM "Voce Incid."
ITEM "Descrizione@80"
ITEM "Usa caradd"
ITEM "Cod. voce ass."
ITEM "Id caradd"
ITEM "Id coll. dich"
ITEM "Coll. dich."
END
ENDPAGE
ENDMASK
TOOLBAR "" 0 19 0 3
BUTTON DLG_OK 10 2
BEGIN
PROMPT -3 -11 ""
END
BUTTON DLG_DELREC 10 2
BEGIN
PROMPT -23 -11 ""
END
BUTTON DLG_CANCEL 10 2
BEGIN
PROMPT -13 -11 ""
END
ENDPAGE
PAGE "" 0 -1 0 19
STRING F_ID 10
BEGIN
PROMPT 1 4 "Identificatore: "
FLAGS "D"
END
STRING F_TIPO 1
BEGIN
PROMPT 1 5 "Tipo cod: "
FLAGS "D"
END
STRING F_CODICE 10
BEGIN
PROMPT 1 6 "Codice voce padre: "
FLAGS "_RD"
CHECKTYPE NORMAL
END
STRING F_COMP 6
BEGIN
PROMPT 1 7 "Num. comp.: "
FLAGS "D"
END
NUMBER F_VOCE_INC 12 0
BEGIN
PROMPT 1 9 "Voce di incidenza: "
FLAGS "Z"
END
STRING F_DESCR 80 50
BEGIN
PROMPT 1 8 "Descrizione: "
END
BOOLEAN F_USA_CARADD
BEGIN
PROMPT 1 15 "Usa caratteristiche addizionali"
END
STRING F_COMPONENTE 12 12
BEGIN
PROMPT 1 10 "Codice voce: "
INPUT LF_VOCI F_COMPONENTE
USE LF_RELVOCI KEY 1
JOIN LF_VOCI TO LF_RELVOCI INTO CODVC=COMP
INPUT LF_RELVOCI->TIPOCOD F_TIPO
INPUT LF_RELVOCI->CODVC F_CODICE
INPUT LF_RELVOCI->IDCOMP F_COMP
DISPLAY "Codice@10" LF_VOCI->CODVC
DISPLAY "Descrizione@40" LF_VOCI->DESCRIZ
OUTPUT F_COMPONENTE LF_VOCI->CODVC
// FLAGS "G"
END
NUMBER F_IDCARADD 12 0
BEGIN
PROMPT 1 12 "Id delle carattestiche addizionali "
USE LF_CARADD KEY 1
INPUT ID F_IDCARADD
OUTPUT F_STAMPA_DETT STD
OUTPUT F_COL_STM_IMP CLI
OUTPUT F_CAR_SOPRA SPI
OUTPUT F_CAR_SOTTO STI
OUTPUT F_DESCR_TOT DST
OUTPUT F_COL_STM_TOT CLT
OUTPUT F_CAR_SOPRA_TOT SPT
OUTPUT F_CAR_SOTTO_TOT STT
OUTPUT F_STAMPA_IMP_TOT SVT
OUTPUT F_LIV_STR LST
OUTPUT F_FLAG_DA ODA
OUTPUT F_LINEA_SALTA_SMP SKI
OUTPUT F_LINEA_SALTA_TOT SKT
OUTPUT F_NON_DSR_VOC_COM NDV
OUTPUT F_RIGA_GRASS RII
OUTPUT F_RIGA_TOT_VC_CMP RIT
OUTPUT F_TVL TVL
CHECKTYPE NORMAL
FLAGS "D"
END
NUMBER F_ID_COLL 6 0
BEGIN
PROMPT 1 13 "Identificatore del collegamento: "
FLAGS "D"
END
BOOLEAN F_USA_COLL
BEGIN
PROMTP 1 16 "Utilizzo collegamento a dichiarazioni"
END
TEXT F_TESTO_GENERALE
BEGIN
PROMPT 1 1 "@B Dati generali"
END
ENDPAGE
PAGE "Car. add." 0 -1 0 19
TEXT F_TESTO_CARADD
BEGIN
PROMPT 1 1 "@B Caratteristiche addizionali"
END
NUMBER F_COL_STM_IMP 1 0
BEGIN
PROMPT 1 3 "Colonna di stampa importo "
END
NUMBER F_COL_STM_TOT 1 0
BEGIN
PROMPT 1 4 "Colonna di stampa totale "
END
STRING F_CAR_SOPRA 1 1
BEGIN
PROMTP 1 5 "Carattere di sopralineatura "
END
STRING F_CAR_SOTTO 1 1
BEGIN
PROMPT 1 6 "Carattere di sottolineatura "
END
STRING F_CAR_SOPRA_TOT 1 1
BEGIN
PROMTP 1 7 "Carattere di sopralineatura totale "
END
STRING F_CAR_SOTTO_TOT 1 1
BEGIN
PROMTP 1 8 "Carattere di sottolineatura totale "
END
NUMBER F_LIV_STR 1 0
BEGIN
PROMPT 1 9 "Livello di struttura "
END
STRING F_FLAG_DA 1 1
BEGIN
PROMPT 1 10 "Segno Dare/Avere per conti d'ordine "
END
STRING F_TVL 1 1
BEGIN
PROMPT 1 11 "Tipo valore "
END
NUMBER F_LINEA_SALTA_SMP 2 0
BEGIN
PROMPT 1 12 "Linee di stampa da saltare (0-72) "
END
NUMBER F_LINEA_SALTA_TOT 2 0
BEGIN
PROMPT 1 13 "Linee di stampa da saltare per tot. "
END
STRING F_DESCR_TOT 80 50
BEGIN
PROMPT 1 15 "Descrizione totale "
END
BOOLEAN F_STAMPA_DETT
BEGIN
PROMPT 1 16 " Stampa dettaglio"
END
BOOLEAN F_STAMPA_IMP_TOT
BEGIN
PROMTP 1 17 " Stampa importo totale su riga voci"
END
BOOLEAN F_NON_DSR_VOC_COM
BEGIN
PROMPT 1 18 " Non stampare la descrizione di voce complessa"
END
BOOLEAN F_RIGA_GRASS
BEGIN
PROMPT 45 16 " Riga voce grassetto"
END
BOOLEAN F_RIGA_TOT_VC_CMP
BEGIN
PROMPT 45 17 " Riga tot. voce c. grass."
END
ENDPAGE
PAGE "Coll. dich." 0 -1 0 19
TEXT F_TESTO_COLLDICH
BEGIN
PROMPT 1 1 "@B Collegamento a dichiarazione redditi"
END
NUMBER F_F4A 3 0
BEGIN
PROMPT 1 5 "Rif. riga mod. 740/f: "
END
STRING F_F4B 1 1
BEGIN
PROMTP 1 6 "Riga bis 740/f: "
END
NUMBER F_P4A 3 0
BEGIN
PROMPT 1 7 "Rif. pros. bil. mod. 740: "
END
STRING F_P4B 1 1
BEGIN
PROMPT 1 8 "Riga bis pros. mod. 740: "
END
NUMBER F_A5A 3 0
BEGIN
PROMPT 1 9 "Rif. riga mod. 750/a: "
END
STRING F_A5B 1 0
BEGIN
PROMTP 1 10 "Riga bis mod 750/a: "
END
NUMBER F_P5A 3 0
BEGIN
PROMPT 1 11 "Rif. pros. bil. mod. 750: "
END
STRING F_P5B 1 1
BEGIN
PROMPT 1 12 "Riga bis pros. mod. 750: "
END
NUMBER F_A6A 3 0
BEGIN
PROMPT 1 13 "Rif. riga mod. 760/a: "
END
STRING F_A6B 1 0
BEGIN
PROMPT 1 14 "Riga bis mod. 760/a: "
END
NUMBER F_X4A 3 0
BEGIN
PROMPT 1 15 "Rif. pros. cred. mod. 740:"
END
STRING F_X4B 1 1
BEGIN
PROMPT 1 16 "Riga bis cred. mod. 740: "
END
NUMBER F_X5A 3 0
BEGIN
PROMTP 1 17 "Rif. pros. cred. mod. 750:"
END
STRING F_X5B 1 1
BEGIN
PROMPT 1 18 "Riga bis cred. mod. 750: "
END
NUMBER F_X6A 3 0
BEGIN
PROMTP 40 5 "Rif. pros. cred. mod. 760:"
END
STRING F_X6B 1 1
BEGIN
PROMTP 40 6 "Riga bis cred. mod. 760: "
END
NUMBER F_P6A 3 0
BEGIN
PROMPT 40 7 "Rif. pros. bil. mod. 760: "
END
STRING F_P6B 1 1
BEGIN
PROMPT 40 8 "Riga bis bil. mod. 760: "
END
NUMBER F_K4A 3 0
BEGIN
PROMTP 40 9 "Rif. mod. 740/k: "
END
NUMBER F_K5A 3 0
BEGIN
PROMPT 40 10 "Rif. mod. 750/k: "
END
NUMBER F_K6A 3 0
BEGIN
PROMTP 40 11 "Rif. mod. 760/k: "
END
ENDPAGE
ENDMASK

BIN
src/R_10_00/ab/ab_ana.doc Executable file

Binary file not shown.

BIN
src/R_10_00/ab/ab_faq.doc Executable file

Binary file not shown.

1
src/R_10_00/ab/ab_prj.doc Executable file
View File

@ -0,0 +1 @@
ÐÏࡱ

2112
src/R_10_00/ab/ablib01.cpp Executable file

File diff suppressed because it is too large Load Diff

434
src/R_10_00/ab/ablib01.h Executable file
View File

@ -0,0 +1,434 @@
#include <relation.h>
#include <relapp.h>
#include <tree.h>
#include <mask.h>
#include "ablib09.h"
#include "analisi.h"
#include "relvoci.h"
#include "relana.h"
#include "saldi.h"
#include "movdett.h"
#include "voci.h"
#define MAX_ID_REL 999999999
#define MAX_ID_MOVDETT 999999
#define NODO_AGGIUNTO "A"
#define NODO_MODIFICATO "M"
#define NODO_RIMOSSO "R"
#define IMMESSO 'I'
#define TRASFERITO 'T'
#define TIPO_ANALISI "A"
#define TIPO_VOCE "V"
#define ID_NULLO 0
#define ID_NULLO_STR "0"
typedef real TNumeric_id;
class TAlbero_movdett : public TBidirectional_tree
{
TToken_string _codtab;
TLocalisamfile *_movdett;
protected:
virtual void node2id(const TObject * node,TString & id) const;
public:
virtual bool has_son() const;
virtual bool has_rbrother() const;
virtual bool has_father() const;
virtual bool has_lbrother() const;
virtual bool goto_root();
virtual bool goto_firstson();
virtual bool goto_father();
virtual bool goto_rbrother();
virtual bool goto_lbrother();
virtual bool goto_node(TString & id)
{return(_movdett->readat(atol(id))==NOERR); }
virtual TObject * curr_node() const;
bool goto_id(const TNumeric_id &id);
TRectype & curr() {return (TRectype &)*curr_node();}
TAlbero_movdett( const char * tabcode);
virtual ~TAlbero_movdett();
};
//Classe per gestire l'albero di relana
class TAlbero_relana : public TBidirectional_tree
{
TString _codtab;
TLocalisamfile *_relana;
TNumeric_id _last_id;
protected:
virtual void node2id(const TObject * node,TString & id) const;
public:
void zero_id() {_last_id = 0;}
virtual bool has_son() const;
virtual bool has_rbrother() const;
virtual bool has_father() const;
virtual bool has_lbrother() const;
virtual bool goto_root();
virtual bool goto_firstson();
virtual bool goto_father();
virtual bool goto_rbrother();
virtual bool goto_lbrother();
virtual bool goto_node(TString & id)
{return(_relana->readat(atol(id))==NOERR); }
virtual TObject * curr_node() const;
bool goto_id(const TNumeric_id &id);
TRectype & curr() {return (TRectype &)*curr_node();}
bool lock();
void unlock();
TNumeric_id &new_id(real id);
TAlbero_relana( const char * tabcode);
virtual ~TAlbero_relana();
};
//Classe per gestire la struttura di una tabella di analisi
// basandosi sull'albero di relvoci
class TAlbero_relvoci : public TTree
{
TString _codtab;
TLocalisamfile *_relvoci;
protected:
virtual void node2id(const TObject* node, TString& id) const;
public:
virtual bool goto_root();
virtual bool has_son() const;
virtual bool goto_firstson();
virtual bool has_rbrother() const;
virtual bool goto_rbrother();
virtual TObject * curr_node() const;
virtual bool goto_node(const TString &id)
{return (_relvoci->readat(atol(id))==NOERR);}
bool has_lbrother() const;
bool goto_lbrother();
TRectype & curr() {return (TRectype &)*curr_node();}
bool lock();
void unlock();
const TString & codtab()
{return _codtab;}
TAlbero_relvoci(const char * tabcode);
virtual ~TAlbero_relvoci() ;
};
// Struttura da albero basata su un file temporaneo cached
class TAlbero_locale : public TBidirectional_tree
{
TLocalisamfile *_f; // da rimuovere !!
protected:
TAssoc_array _status_node;
TRWrecord_cache * _local_cache;
TNumeric_id _last_insert_id;
TRectype *_currnode;
virtual const char * get_headkey() const {return NULL;}
virtual const char * id_fieldname() const {return NULL;}
public:
// debug
void write_cache() { _local_cache->flush(); }
void clear_cache()
{
_local_cache->clear();
_last_insert_id = 0;
}
virtual bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id, const char trasf_immes = TRASFERITO) {return FALSE;}
virtual bool delete_node(const TNumeric_id &id) {return FALSE;}
virtual bool delete_tree() { return FALSE;}
virtual void zero() {;}
virtual bool make_root(TBaseisamfile & saldi) {return FALSE;}
virtual void link_succ_zero(const TNumeric_id currid) {;}
virtual void link_son_zero(const TNumeric_id currid) {;}
virtual TObject * curr_node() const {return _currnode;}
TRectype & current() const {return (TRectype &)*curr_node();}
TRWrecord_cache & current_cache() const {return *_local_cache;}
// ***** gestione interfaccia Database/copia locale
virtual TRectype extract_dirtynode(TString &id, TString& status) { TRectype rec(*_currnode); return rec;}
int dirty_nodes() { return _status_node.items();}
void set_status_node(const TString &id, const char *status);
TString* get_status_node(const TString &id)
{return (TString*)_status_node.objptr(id);}
virtual void goto_node(const TNumeric_id id) {;}
virtual void goto_node(TRectype &node) {*_currnode = node;}
virtual bool goto_node(const TString & id) {TNumeric_id nid(id); goto_node(nid); return TRUE;}
virtual void node2id(const TObject* node, TString& id) const {;}
virtual bool goto_firstson() {return FALSE;}
virtual bool goto_rbrother() {return FALSE;}
virtual bool goto_root() {return FALSE;}
/* virtual const char * idfather_fieldname() const {return NULL;}
virtual const char * idson_fieldname() const {return NULL;}
virtual const char * idsucc_fieldname() const {return NULL;}
virtual const char * idprec_fieldname() const {return NULL;}
virtual void put_headkey(TRectype &) {;}
virtual bool remove_subtree(const TNumeric_id lastnode_id) { return TRUE;}
virtual TNumeric_id &new_id(TNumeric_id) { real i; return i;}
virtual bool has_father() const {return TRUE;}
virtual bool goto_father() {return TRUE;}
virtual bool has_rbrother() const {return TRUE;}
virtual bool has_lbrother() const {return TRUE;}
virtual bool goto_lbrother() {return TRUE;}
virtual bool goto_son_first_level() {return TRUE;}
virtual void curr_id(TString& id) const
{
node2id(curr_node(), id);
}
*/
TAlbero_locale(int filenum);
virtual ~TAlbero_locale();
};
class TAlbero_locale_link : public TAlbero_locale
{
// TLocalisamfile *_c;
// TRWrecord_cache * _local_cache_carad;
protected:
virtual const char * idfather_fieldname() const pure ;
virtual const char * idson_fieldname() const pure;
virtual const char * idsucc_fieldname() const pure;
virtual const char * idprec_fieldname() const pure;
virtual const char * id_fieldname() const pure;
virtual const char * get_headkey() const pure;
virtual void put_headkey(TRectype &) pure;
virtual void node2id(const TObject* node, TString& id) const
{
const TRectype *rec = (const TRectype *)node;
id = rec->get_real(id_fieldname()).string();
}
virtual bool remove_subtree(const TNumeric_id lastnode_id);
virtual TNumeric_id &new_id(TNumeric_id);
public:
virtual bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id, const char trasf_immes = TRASFERITO);
virtual bool delete_node(const TNumeric_id &id);
virtual bool delete_tree();
virtual void zero();
virtual void goto_node(const TNumeric_id id);
virtual void goto_node(TRectype &node) {*_currnode = node;}
virtual bool goto_node(const TString & id) {TNumeric_id nid(id); goto_node(nid); return TRUE;}
virtual bool make_root(TBaseisamfile & saldi) pure;
virtual bool get_description(TString& desc) const pure;
virtual bool has_son() const;
virtual bool goto_firstson();
virtual bool has_father() const;
virtual bool goto_father();
virtual bool has_rbrother() const;
virtual bool goto_rbrother();
virtual bool has_lbrother() const;
virtual bool goto_lbrother();
virtual bool goto_son_first_level();
// virtual bool has_root() const {return FALSE;}
virtual bool goto_root();
virtual void link_succ_zero(const TNumeric_id currid);
virtual void link_son_zero(const TNumeric_id currid);
virtual TRectype extract_dirtynode(TString &id, TString& status);
TAlbero_locale_link(int filenum);
virtual ~TAlbero_locale_link() {;}
};
class TAlbero_locale_relvoci: public TAlbero_locale
{
protected:
// virtual bool remove_subtree(const TNumeric_id lastnode_id);
public:
virtual bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id, const char trasf_immes = TRASFERITO);
virtual bool delete_node(const TNumeric_id &id);
virtual bool goto_node(const TString &key);
/**********************/
virtual bool delete_tree() { return FALSE;}
virtual void zero() {;}
virtual bool make_root(TBaseisamfile & saldi) {return FALSE;}
virtual bool has_rbrother() const;
virtual bool goto_rbrother();
virtual bool has_lbrother() const;
virtual bool goto_lbrother();
virtual TRectype extract_dirtynode(TString &id, TString& status);
TNumeric_id new_id();
// virtual bool delete_tree();
// virtual bool has_son() const;
// virtual bool goto_firstson();
// virtual bool has_father() const;
// virtual bool goto_father();
// virtual bool goto_son_first_level();
TAlbero_locale_relvoci();
virtual ~TAlbero_locale_relvoci() {;}
};
// Copia locale dell'albero di una tabella analisi
class TLocal_relana3 : public TAlbero_locale_link
{
protected:
virtual const char * idfather_fieldname() const {return ABRA_IDPADRE;}
virtual const char * idson_fieldname() const {return ABRA_IDFIGLIO;}
virtual const char * idsucc_fieldname() const {return ABRA_IDSUCC;}
virtual const char * idprec_fieldname() const {return ABRA_IDPREC;}
virtual const char * id_fieldname() const {return ABRA_ID;}
virtual const char * get_headkey() const {return " ";}
virtual void put_headkey(TRectype & node) {node.put(ABRA_CODAN,get_headkey());}
public:
virtual bool make_root(TBaseisamfile & saldi);
virtual bool get_description(TString& desc) const;
TLocal_relana3();
virtual ~TLocal_relana3();
};
// Copia locale dell'albero dei dettagli di un saldo
class TLocal_balance3 : public TAlbero_locale_link
{
protected:
virtual const char * idfather_fieldname() const {return ABMD_IDPADRE;}
virtual const char * idson_fieldname() const {return ABMD_IDFIGLIO;}
virtual const char * idsucc_fieldname() const {return ABMD_IDSUCC;}
virtual const char * idprec_fieldname() const {return ABMD_IDPREC;}
virtual const char * id_fieldname() const {return ABMD_ID;}
virtual const char * get_headkey() const {return " | | | | ";}
virtual void put_headkey(TRectype & node) ;
public:
virtual bool make_root(TBaseisamfile & saldi);
virtual bool get_description(TString& desc) const;
TLocal_balance3();
virtual ~TLocal_balance3();
};
class TAlbero_AB: public TRectype
{
protected:
TAlbero_locale *_inter_tree;
virtual int commit_body() const;
virtual int read_body(bool lockstruct) {return 0;} //DA FARE
virtual void put_headkey(TRectype &rec) const {;} //DA FARE
TRectype * _newrec; //buffer per l'inserimento dodo per nodo
public:
TAlbero_AB(int filenum);
virtual ~TAlbero_AB();
virtual int read(TBaseisamfile& analisi, word isop=_isequal, word lockop=_nolock);
virtual int readat(TBaseisamfile& f, TRecnotype nrec, word lockop = _nolock);
virtual int write(TBaseisamfile& analisi) const;
virtual int rewrite(TBaseisamfile& analisi) const;
virtual int remove(TBaseisamfile& f) const;
virtual bool remove_node(const TNumeric_id &id) {return FALSE;}
virtual bool insert_new_node() {return FALSE;}
virtual void zero();
TAlbero_locale * user_tree()
{return _inter_tree;}
};
class TRecord : public TObject
{
TLocalisamfile *_r; // da rimuovere !!
protected:
TAssoc_array _status_node_record;
TRWrecord_cache * _local_cache_record;
TRectype *_currrec;
public:
// debug
void write_cache() { _local_cache_record->flush(); }
TRectype & current_rec() const {return *_currrec;}
TRWrecord_cache & current_cache_record() const {return *_local_cache_record;}
virtual TRectype extract_dirtynode(TString &id, TString& status);
int dirty_nodes() { return _status_node_record.items();}
void set_status_node(const TString &id, const char *status);
TString* get_status_node(const TString &id)
{return (TString*)_status_node_record.objptr(id);}
TRecord(int filenum);
virtual ~TRecord();
};
class TAnalisi_bil: public TAlbero_AB
{
class TArray_fratelli: public TAssoc_array
{
public:
void setkey(const char *tipocod, const char *codvc, TToken_string &key) const;
bool find1stkey(const char *tipocod, const char *codvc, TToken_string &key);
void mark_used(const char *key);
bool used(TObject *o);
};
TArray_fratelli _nodifratelli;
TLocalisamfile *_analisi;
TLocalisamfile *_voci;
TAlbero_relvoci *_relaz;
TAlbero_relana *_ana;
TAlbero_locale *_inter_tree_relvoci;
protected:
void naviga_relazioni(const TNumeric_id & id_relana,const TNumeric_id & prec,const TNumeric_id & padre );
TRectype * sincronizza_relana(const TNumeric_id &begin_relana,TNumeric_id &id_relana);
bool lock_struttura();
bool unlock_struttura();
bool lock_tabella();
bool unlock_tabella();
virtual int read_body(bool lockstruct);
virtual int commit_body() const;
virtual void put_headkey(TRectype &rec) const;
void prova_inserimento();
public:
virtual bool remove_node(const TNumeric_id &id);
virtual bool insert_new_node(TToken_string &codice);
virtual void modify_node(TToken_string &codice);
TAnalisi_bil();
virtual ~TAnalisi_bil() ;
TAlbero_locale * user_tree_voc()
{return _inter_tree_relvoci;}
const TString &type() {return get(ABAN_TIPOAN);}
void set_type(const char * tipo) {put(ABAN_TIPOAN,tipo);}
};
class TABsaldo: public TAlbero_AB
{
TLocalisamfile *_saldi;
TAlbero_movdett *_mov;
TLocalisamfile *_movdett;
protected:
virtual int read_body(bool lockstruct);
virtual void put_headkey(TRectype &rec) const;
void naviga_movdett();
void prova_inserimento();
public:
virtual bool remove_node(const TNumeric_id &id) {return FALSE;} //da fare
TABsaldo();
virtual ~ TABsaldo();
};

148
src/R_10_00/ab/ablib09.cpp Executable file
View File

@ -0,0 +1,148 @@
///////////////////////////////////////////////////////////
// Cache
///////////////////////////////////////////////////////////
#include "ablib09.h"
#define RWCACHE_SIZE 100
// funzione di default: prende una chiave a caso chiave
const TString & TRWrecord_cache::getkey2discard()
{
THash_object * o=get_some_obj();
CHECK(o,"E' stata chiamata la funzione getkey2discard con la cache vuota");
return o->key();
}
//Scarica una parte della cache
void TRWrecord_cache::discard(const TString & vittima)
{
if (items()) //Usa l'items di TFile_cahe che richiame l'items dell'assoc_array _cache
{
if (_flags.is_key(vittima)) //_flags è un assoc_array di TRWcache, usa is_key di assoc_array
{
const char fl=((TString &)_flags[vittima])[1];
// record modificato o nuovo
int err;
TRectype & rec=(TRectype & )TRecord_cache::get(vittima);
file().curr()=rec;
if (fl == 'D')
{
err=file().rewrite();
if (err!=NOERR)
error_box("Errore nella riscrittura della cache");
} else {
err=file().write();
if (err!=NOERR)
if (err == _isreinsert)
file().rewrite();
else
error_box("Errore nella scrittura della cache");
}
_flags.remove(vittima);
}//Se non esiste nel assoc_array di TRWcache
_cache.remove(vittima);
}
}
const TRectype& TRWrecord_cache::get(const char* chiave)
{
if (items()>=RWCACHE_SIZE)
discard(getkey2discard());
const TRectype & rec=TRecord_cache::get(chiave);
if (io_result() != NOERR)
{
// record non trovato: è nuovo
_flags.add(chiave,new TString("N"));
}
return rec;
}
void TRWrecord_cache::put(const TRectype &r)
{
test_firm();
TToken_string cachekey;
if (!r.empty())
{
const RecDes& recd = r.rec_des(); // Descrizione del record della testata
const KeyDes& kd = recd.Ky[key_number()-1]; // Elenco dei campi della chiave
for (int i = file().tab() ? 1: 0; i < kd.NkFields; i++) // Riempie la chiave selezionata
{
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = recd.Fd[nf];
cachekey.add(r.get(rf.Name));
}
}
TObject* obj = _cache.objptr(cachekey);
if (obj != NULL)
{
// esiste in cache ; tenta di settare il flag a "D"irty; se il flag esiste già è a
TRectype & rec=(TRectype &)*obj;
rec=r;
_flags.add(cachekey , new TString("D"));
} else {
// non esiste in cache
obj = rec2obj(r);
_cache.add(cachekey, obj);
// qui assume che non esista nemmeno su file, perciò sia "N"uovo; al flush correggerà l'errore
_flags.add(cachekey , new TString("N"));
}
if (items()>=RWCACHE_SIZE)
discard(getkey2discard());
}
//Vuota una cache
void TRWrecord_cache::clear()
{
while (items()>0)
{
const TString & vittima=getkey2discard();
if (_flags.is_key(vittima))
_flags.remove(vittima);
_cache.remove(vittima);
}
}
//Forza la scrittura sulla cache
void TRWrecord_cache::flush()
{
while (items()>0)
{
discard(TRWrecord_cache::getkey2discard());
}
}
THash_object * TRWrecord_cache::get_some_obj()
{
if (items()==0) //Usa l'items() di TFilecache fa items() di un assoc_array _cahce
return NULL;
THash_object * o;
while ((o=_cache.get_hashobj()) == NULL) ; //Ritorna l'oggetto e la relativa chiave dell'assoc_array _cache
return o;
}
//Costruttori vari
TRWrecord_cache::TRWrecord_cache(TLocalisamfile *f, int key, bool lock)
:TRecord_cache(f,key)
{
if (lock)
file().lock();
}
TRWrecord_cache::TRWrecord_cache(int num, int key, bool lock)
:TRecord_cache(num,key)
{
if (lock)
file().lock();
}
TRWrecord_cache::~TRWrecord_cache()
{
flush();
}

28
src/R_10_00/ab/ablib09.h Executable file
View File

@ -0,0 +1,28 @@
#ifndef _ABLI09_H
#define _ABLI09_H
#ifndef _RECARRAY_H
#include <recarray.h>
#endif
class TRWrecord_cache : public TRecord_cache
{
TAssoc_array _flags;
protected:
THash_object * get_some_obj();
virtual const TString & getkey2discard();
public:
virtual void discard(const TString & k);
virtual void put(const TRectype &r);
virtual const TRectype& get(const char* chiave);
void clear();
void flush();
TRWrecord_cache(TLocalisamfile *f, int key = 1, bool lock=FALSE);
TRWrecord_cache(int num, int key = 1, bool lock=FALSE);
TRWrecord_cache(const char* table, int key = 1, bool lock=FALSE);
virtual ~TRWrecord_cache() ;
};
#endif

7
src/R_10_00/ab/abpcon.h Executable file
View File

@ -0,0 +1,7 @@
#define ABPC_CODCBL "CODCBL"
#define ABPC_LIVELLO "LIVELLO"
#define ABPC_DESCRIZ "DESCRIZ"
#define ABPC_INDBIL "INDBIL"
#define ABPC_CODCONTR "CODCONTR"
#define ABPC_SOSPESO "SOSPESO"
#define ABPC_DETT "DETT"

73
src/R_10_00/ab/abstarb.rep Executable file
View File

@ -0,0 +1,73 @@
<report name="abstarb" lpi="6">
<font face="Courier New" size="10" />
<section keep_with_next="1" type="Head">
<field type="Stringa" width="50">
<font italic="1" face="Courier New" bold="1" size="10" />
<source>#SYSTEM.RAGSOC</source>
</field>
<field y="1" type="Testo" valign="center" align="center" width="96" height="2" text="Tabella Archiviazione Bilanci">
<font face="Courier New" bold="1" size="14" />
</field>
<field border="2" x="1" y="3.5" type="Linea" width="93" height="0" />
<field x="2" y="4" type="Testo" width="6" text="Codice">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="11" y="4" type="Testo" width="4" text="Anno">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="18" y="4" type="Testo" width="8" text="Cod.Per.">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="29" y="4" type="Testo" width="9" text="Tipo bil.">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="41" y="4" type="Testo" width="9" text="Data arc.">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="54" y="4" type="Testo" width="9" text="Data rip.">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="67" y="4" type="Testo" width="11" text="Per. chiuso ">
<font face="Courier New" bold="1" size="10" />
</field>
<field border="2" x="1" y="5.5" type="Linea" width="93" height="0" />
</section>
<section keep_with_next="1" type="Head" level="1" />
<section keep_with_next="1" type="Body" />
<section keep_with_next="1" type="Body" level="1">
<field x="2" type="Stringa" link="ARB.CODTAB[1,5]" width="5">
<source>CODTAB[1,5]</source>
</field>
<field x="11" type="Stringa" link="ARB.CODTAB[6,9]" width="4">
<source>CODTAB[6,9]</source>
</field>
<field x="20" type="Stringa" link="ARB.CODTAB[10,12]" width="3">
<source>CODTAB[10,12]</source>
</field>
<field x="32" type="Stringa" link="ARB.CODTAB[13,15]" width="3">
<source>CODTAB[13,15]</source>
</field>
<field x="41" type="Data" width="10">
<source>D0</source>
</field>
<field x="54" type="Data" width="10">
<source>D1</source>
</field>
<field x="72" type="Stringa" width="1">
<source>B0</source>
</field>
</section>
<section keep_with_next="1" type="Foot" height="3">
<field border="2" x="1" y="0.5" type="Linea" width="93" height="0" />
<field x="2" y="1" type="Data" width="10">
<source>#SYSTEM.DATE</source>
</field>
<field x="90" y="1" type="Numero" align="right" width="3">
<source>#PAGE</source>
</field>
<field border="2" x="1" y="2.5" type="Linea" width="93" height="0" />
</section>
<section keep_with_next="1" type="Foot" level="1" />
<sql>USE ARB</sql>
</report>

39
src/R_10_00/ab/abstarb.uml Executable file
View File

@ -0,0 +1,39 @@
#include "ab1200.h"
TOOLBAR "topbar" 0 0 0 2
#include <printbar.h>
ENDPAGE
PAGE "Stampa tabella archiviazione bilanci" 0 2 0 0
STRING F_INIZIO1 5
BEGIN
PROMPT 3 1 "Da codice "
HELP "Codice da cui iniziare a stampare. Vuoto = inizio archivio"
USE %ARB
INPUT CODTAB[1,5] F_INIZIO1
DISPLAY "Codice" CODTAB[1,5]
DISPLAY "Anno@15" CODTAB[6,9]
DISPLAY "Periodo@15" CODTAB[10,12]
DISPLAY "Tipo@15" CODTAB[13,15]
OUTPUT F_INIZIO1 CODTAB[1,5]
GROUP 1
FIELD CODTAB[1,5]
FLAGS "RU"
END
STRING F_FINE1 5
BEGIN
PROMPT 4 3 "A codice "
HELP "Codice a cui terminare la stampa. Vuoto = fine archivio"
COPY USE F_INIZIO1
INPUT CODTAB[1,5] F_FINE1
COPY DISPLAY F_INIZIO1
OUTPUT F_FINE1 CODTAB[1,5]
GROUP 2
FIELD CODTAB[1,5]
FLAGS "RU"
END
ENDPAGE
ENDMASK

39
src/R_10_00/ab/abstntb.rep Executable file
View File

@ -0,0 +1,39 @@
<report name="abstntb" lpi="6">
<font face="Courier New" size="10" />
<section keep_with_next="1" type="Head">
<field type="Testo" valign="center" align="center" width="96" height="2" text="Tabella Tipi di Bilancio">
<font face="Courier New" bold="1" size="14" />
</field>
<field border="2" x="1" y="2.5" type="Linea" width="93" height="0" />
<field x="2" y="3" type="Testo" width="10" text="Codice">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="11" y="3" type="Testo" width="12" text="Descrizione">
<font face="Courier New" bold="1" size="10" />
</field>
<field border="2" x="1" y="4.5" type="Linea" width="93" height="0" />
</section>
<section keep_with_next="1" type="Head" level="1" />
<section keep_with_next="1" type="Body" />
<section keep_with_next="1" type="Body" level="1">
<field x="2" type="Stringa" link="%NTB.CODTAB[1,2]" width="2">
<source>CODTAB[1,2]</source>
</field>
<field x="11" type="Stringa" width="80">
<source>S0</source>
</field>
</section>
<section keep_with_next="1" type="Foot" height="3">
<field border="2" x="1" y="0.5" type="Linea" width="93" height="0" />
<field x="2" y="1" type="Data" width="10">
<source>#SYSTEM.DATE</source>
</field>
<field x="90" y="1" type="Numero" align="right" width="3">
<source>#PAGE</source>
</field>
<field border="2" x="1" y="2.5" type="Linea" width="93" height="0" />
</section>
<section keep_with_next="1" type="Foot" level="1" />
<sql>USE %NTB</sql>
</report>

37
src/R_10_00/ab/abstntb.uml Executable file
View File

@ -0,0 +1,37 @@
#include "ab1200.h"
TOOLBAR "topbar" 0 0 0 2
#include <printbar.h>
ENDPAGE
PAGE "Stampa tabella tipi di bilancio" 0 2 0 0
STRING F_INIZIO1 2
BEGIN
PROMPT 3 1 "Da codice "
HELP "Codice da cui iniziare a stampare. Vuoto = inizio archivio"
USE %NTB
INPUT CODTAB F_INIZIO1
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@40" S0
OUTPUT F_INIZIO1 CODTAB
GROUP 1
FIELD CODTAB
FLAGS "RU"
END
STRING F_FINE1 2
BEGIN
PROMPT 4 3 "A codice "
HELP "Codice a cui terminare la stampa. Vuoto = fine archivio"
COPY USE F_INIZIO1
INPUT CODTAB F_FINE1
COPY DISPLAY F_INIZIO1
OUTPUT F_FINE1 CODTAB
GROUP 2
FIELD CODTAB
FLAGS "RU"
END
ENDPAGE
ENDMASK

70
src/R_10_00/ab/abstpdb.rep Executable file
View File

@ -0,0 +1,70 @@
<report name="abstpdb" lpi="6">
<font face="Courier New" size="10" />
<section keep_with_next="1" type="Head">
<field type="Testo" valign="center" align="center" width="96" height="2" text="Tabella Perodi di Bilancio">
<font face="Courier New" bold="1" size="14" />
</field>
<field border="2" x="1" y="2.5" type="Linea" width="93" height="0" />
<field x="2" y="3" type="Testo" width="4" text="Cod.">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="8" y="3" type="Testo" width="11" text="Descrizione">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="58" y="3" type="Testo" width="12" text="gg/mm inizio">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="73" y="3" type="Testo" width="10" text="gg/mm fine">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="85" y="3" type="Testo" width="9" text="Num. Anni">
<font face="Courier New" bold="1" size="10" />
</field>
<field x="8" y="4" type="Testo" width="40" text="Descrizione alternativa stampa raffronto ">
<font face="Courier New" bold="1" size="10" />
</field>
<field border="2" x="1" y="5.5" type="Linea" width="93" height="0" />
</section>
<section keep_with_next="1" type="Head" level="1" />
<section keep_with_next="1" type="Body" />
<section keep_with_next="1" type="Body" level="1">
<field x="2" type="Stringa" link="%PDB.CODTAB[1,3]" width="3">
<source>CODTAB[1,3]</source>
</field>
<field x="8" type="Stringa" width="50">
<source>S0</source>
</field>
<field x="61" type="Numero" align="right" width="2">
<source>I0[1,2]</source>
</field>
<field x="65" type="Numero" align="right" width="2">
<source>I1[1,2]</source>
</field>
<field x="77" type="Numero" align="right" width="2">
<source>I2[1,2]</source>
</field>
<field x="81" type="Numero" align="right" width="2">
<source>I3[1,2]</source>
</field>
<field x="90" type="Numero" align="right" width="4">
<source>I4[1,4]</source>
</field>
<field x="8" y="1" type="Stringa" width="50">
<source>S1</source>
</field>
<field border="1" x="1" y="2.5" type="Linea" width="93" height="0" />
</section>
<section keep_with_next="1" type="Foot" height="3">
<field border="2" x="1" y="0.5" type="Linea" width="93" height="0" />
<field x="2" y="1" type="Data" width="10">
<source>#SYSTEM.DATE</source>
</field>
<field x="90" y="1" type="Numero" align="right" width="3">
<source>#PAGE</source>
</field>
<field border="2" x="1" y="2.5" type="Linea" width="93" height="0" />
</section>
<section keep_with_next="1" type="Foot" level="1" />
<sql>USE %PDB</sql>
</report>

37
src/R_10_00/ab/abstpdb.uml Executable file
View File

@ -0,0 +1,37 @@
#include "ab1200.h"
TOOLBAR "topbar" 0 0 0 2
#include <printbar.h>
ENDPAGE
PAGE "Stampa tabella tipi di bilancio" 0 2 0 0
STRING F_INIZIO1 2
BEGIN
PROMPT 3 1 "Da codice "
HELP "Codice da cui iniziare a stampare. Vuoto = inizio archivio"
USE %PDB
INPUT CODTAB F_INIZIO1
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@40" S0
OUTPUT F_INIZIO1 CODTAB
GROUP 1
FIELD CODTAB
FLAGS "UZ"
END
STRING F_FINE1 2
BEGIN
PROMPT 4 3 "A codice "
HELP "Codice a cui terminare la stampa. Vuoto = fine archivio"
COPY USE F_INIZIO1
INPUT CODTAB F_FINE1
COPY DISPLAY F_INIZIO1
OUTPUT F_FINE1 CODTAB
GROUP 2
FIELD CODTAB
FLAGS "UZ"
END
ENDPAGE
ENDMASK

10
src/R_10_00/ab/abtbarb.h Executable file
View File

@ -0,0 +1,10 @@
// campi maschera batbarb.uml
#define F_CODTAB_DITTA 101
#define F_CODTAB_ESE 102
#define F_CODTAB_PER 103
#define F_CODTAB_TIPO 104
#define F_SCEGLI 105
#define F_DI 106
#define F_DF 107

116
src/R_10_00/ab/abtbarb.uml Executable file
View File

@ -0,0 +1,116 @@
#include "abtbarb.h"
TOOLBAR "" 0 0 0 2
#include <relapbar.h>
ENDPAGE
PAGE "Tabella archiviazione bilanci" 0 2 0 0
GROUPBOX DLG_NULL 74 12
BEGIN
PROMPT 2 0 ""
FLAGS "R"
END
STRING F_CODTAB_DITTA 5
BEGIN
PROMTP 4 3 "Codice ditta "
HELP "Inserire il codice della ditta"
FIELD CODTAB[1,5]
FLAG "RU"
KEY 1
USE LF_NDITTE KEY 1
INPUT LF_NDITTE->CODDITTA F_CODTAB_DITTA
DISPLAY "Codice@5" LF_NDITTE->CODDITTA
DISPALY "Ragione sociale@45" LF_NDITTE->RAGSOC
OUTPUT F_CODTAB_DITTA LF_NDITTE->CODDITTA
CHECKTYPE REQUIRED
END
STRING F_CODTAB_ESE 4
BEGIN
PROMTP 4 5 "Anno "
HELP "Inserire l'anno di esercizio"
FIELD CODTAB[6,9]
KEY 1
USE %ARB KEY 1
INPUT %ARB->CODTAB[6,9] F_CODTAB_ESE
DISPLAY "Anno@4" CODTAB[6,9]
DISPLAY "Codice@5" CODTAB[1,5]
DISPALY "Periodo@3" CODTAB[10,12]
DISPLAY "Tipo@3" CODTAB[13,15]
OUTPUT F_CODTAB_DITTA CODTAB[1,5]
OUTPUT F_CODTAB_ESE CODTAB[6,9]
OUTPUT F_CODTAB_PER CODTAB[10,12]
OUTPUT F_CODTAB_TIPO CODTAB[13,15]
OUTPUT F_SCEGLI B0
OUTPUT F_DI D0
OUTPUT F_DF D1
CHECKTYPE REQUIRED
END
STRING F_CODTAB_PER 3
BEGIN
PROMTP 4 7 "Codice perido "
HELP "Inserire il codeice che identifica il tipo periodo"
FIELD CODTAB[10,12]
FLAG "RU"
KEY 1
USE %PDB KEY 1
INPUT %PDB->CODTAB F_CODTAB_PER
DISPLAY "Cod@3" %PDB->CODTAB
DISPALY "Descrizione@35" %PDB->S0
DISPLAY "Gi" %PDB->I0
DISPLAY "Mi" %PDB->I1
DISPLAY "Gf" %PDB->I2
DISPLAY "Mf" %PDB->I3
DISPLAY "N.anni" %PDB->I4
OUTPUT F_CODTAB_PER %PDB->CODTAB
CHECKTYPE REQUIRED
END
STRING F_CODTAB_TIPO 3
BEGIN
PROMPT 4 9 "Tipo di bilancio "
HELP "Inserire il codice che identifica il tipo"
FIELD CODTAB[13,15]
FLAG "RU"
KEY 1
USE %NTB KEY 1
INPUT %NTB->CODTAB F_CODTAB_TIPO
DISPLAY "Cod@5" %NTB->CODTAB
DISPLAY "Descrizione@40" %NTB->S0
OUTPUT F_CODTAB_TIPO %NTB->CODTAB
CHECKTYPE REQUIRED
END
BOOLEAN F_SCEGLI
BEGIN
PROMPT 4 12 "Periodo chiuso"
FIELD B0
END
DATE F_DI
BEGIN
PROMPT 4 14 "Data di archiviazione "
FIELD D0
END
DATE F_DF
BEGIN
PROMPT 4 16 "Data di ripristino "
FIELD D1
NUM_EXPR (#F_DF==0)||(#F_DF<#F_DI)
WARNING "La data di ripristino deve essere superiore a quella di archiviazione"
CHECKTYPE NORMAL
END
ENDPAGE
ENDMASK

4
src/R_10_00/ab/abtbntb.h Executable file
View File

@ -0,0 +1,4 @@
// campi della maschera batbntb.uml
#define F_CODTAB 101
#define F_DESCR 102

48
src/R_10_00/ab/abtbntb.uml Executable file
View File

@ -0,0 +1,48 @@
#include "abtbntb.h"
TOOLBAR "" 0 0 0 2
#include <relapbar.h>
ENDPAGE
PAGE "Tabella tipi di bilancio" 0 2 0 0
GROUPBOX DLG_NULL 76 9
BEGIN
PROMPT 2 0 ""
FLAG "R"
END
STRING F_CODTAB 2
BEGIN
PROMPT 4 3 "Codice di bilancio "
HELP "Codice della tabella tipi di bilancio"
FLAG "RU"
FIELD CODTAB
KEY 1
USE %NTB KEY 1
INPUT CODTAB F_CODTAB
DISPLAY "Codice@2" CODTAB
DISPLAY "Descrizione@40" S0
OUTPUT F_CODTAB CODTAB
OUTPUT F_DESCR S0
CHECKTYPE REQUIRED
END
STRING F_DESCR 70 40
BEGIN
PROMPT 4 6 "Descrizione "
HELP "Descrizione del codice tabella tipi di bilancio"
KEY 2
USE %NTB KEY 2
INPUT S0 F_DESCR
DISPLAY "Descrizione@40" S0
DISPLAY "Codice@2" CODTAB
COPY OUTPUT F_CODTAB
CHECKTYPE REQUIRED
FIELD S0
END
ENDPAGE
ENDMASK

10
src/R_10_00/ab/abtbpdb.h Executable file
View File

@ -0,0 +1,10 @@
// campi maschera batbpdb.uml
#define F_CODTAB 101
#define F_DESCR 102
#define F_GIORNO_INI 103
#define F_MESE_INI 104
#define F_GIORNO_FINE 105
#define F_MESE_FINE 106
#define F_DESCRAGG 107
#define F_NUM_ANNI 108

110
src/R_10_00/ab/abtbpdb.uml Executable file
View File

@ -0,0 +1,110 @@
#include "abtbpdb.h"
TOOLBAR "" 0 0 0 2
#include <relapbar.h>
ENDPAGE
PAGE "Tabella periodi di bilancio" 0 2 0 0
GROUPBOX DLG_NULL 76 6
BEGIN
PROMPT 1 0 ""
FLAGS "R"
END
STRING F_CODTAB 2
BEGIN
PROMPT 2 2 "Codice periodo "
HELP "Inserire il codice identificativo del periodo prescelto"
FLAS "UZ"
FIELD CODTAB
KEY 1
USE %PDB KEY 1
INPUT CODTAB F_CODTAB
DISPLAY "Codice@3" CODTAB
DISPLAY "Descrizione@40" S0
DISPLAY "gg.inizio@3" I0
DISPLAY "mm.inizio@3" I1
DISPLAY "gg.fine@3" I2
DISPLAY "mm.fine@3" I3
DISPLAY "Numero anni@3" I4
OUTPUT F_CODTAB CODTAB
OUTPUT F_DESCR S0
CHECKTYPE REQUIRED
END
STRING F_DESCR 70 40
BEGIN
PROMPT 2 4 "Descrizione "
HELP "Descrizione del codice tabella periodi di bilancio"
FIELD S0
KEY 2
USE %PDB KEY 2
INPUT S0 F_DESCR
DISPLAY "Descrizione@40" S0
DISPLAY "Codice@3" CODTAB
DISPLAY "gg.inizio@3" I0
DISPLAY "mm.inizio@3" I1
DISPLAY "gg.fine@3" I2
DISPLAY "mm.fine@3" I3
DISPLAY "Numero anni@3" I4
COPY OUTPUT F_CODTAB
CHECKTYPE REQUIRED
END
NUMBER F_GIORNO_INI 2
BEGIN
PROMPT 2 8 "Inizio periodo: giorno "
HELP "Inserire il giorno relativo al periodo di inizio"
FIELD I0
FLAGS "RU"
CHECKTYPE REQUIRED
END
NUMBER F_MESE_INI 2
BEGIN
PROMPT 32 8 "mese "
HELP "Inserire il mese relativo al periodo di inizio"
FIELD I1
FLAGS "RU"
CHECKTYPE REQUIRED
END
NUMBER F_GIORNO_FINE 2
BEGIN
PROMPT 2 10 "Fine periodo: giorno "
HELP "Inserire il giorno relativo alla fine del periodo"
FIELD I2
FLAGS "RU"
CHECKTYPE REQUIRED
END
NUMBER F_MESE_FINE 2
BEGIN
PROMPT 32 10 "mese "
HELP "Inserire il mese relativo alla fine del periodo"
FIELD I3
FLAGS "RU"
CHECKTYPE REQUIRED
END
NUMBER F_NUM_ANNI 1
BEGIN
PROMPT 2 12 "Numero di anni "
HELP "Inserire il numero di anni"
FIELD I4
FLAGS "RU"
CHECKTYPE NORMAL
END
STRING F_DESCRAGG 70 30
BEGIN
PROMPT 2 15 "Descrizione alternativa per stampa raffronti "
FIELD S1
END
ENDPAGE
ENDMASK

10
src/R_10_00/ab/analisi.h Executable file
View File

@ -0,0 +1,10 @@
//Nomi dei campi nel tracciato record di LF_ANALISI
#ifndef _ANALISI_H
#define _ANALISI_H
#define ABAN_CODAN "CODAN"
#define ABAN_DESCRIZ "DESCRIZ"
#define ABAN_TIPOAN "TIPOAN"
#define ABAN_NOTE "NOTE"
#endif //_ANALISI_H

26
src/R_10_00/ab/caradd.h Executable file
View File

@ -0,0 +1,26 @@
//Nomi dei campi del file LF_CARADD
#ifndef _CARADD_H
#define _CARADD_H
#define ABCA_ID "ID"
#define ABCA_STD "STD"
#define ABCA_CLI "CLI"
#define ABCA_SPI "SPI"
#define ABCA_STI "STI"
#define ABCA_DST "DST"
#define ABCA_CLT "CLT"
#define ABCA_SPT "SPT"
#define ABCA_STT "STT"
#define ABCA_SVT "SVT"
#define ABCA_LST "LST"
#define ABCA_ODA "ODA"
#define ABCA_SKI "SKI"
#define ABCA_SKT "SKT"
#define ABCA_NDV "NDV"
#define ABCA_RII "RII"
#define ABCA_RIT "RIT"
#define ABCA_TVL "TVL"
#endif //_CARADD_H

7
src/R_10_00/ab/colldich.h Executable file
View File

@ -0,0 +1,7 @@
//Nomi dei campi del file LF_COLLDICH
#ifndef _COLLDICH_H
#define _COLLDICH_H
#define ABCD_ID "ID"
#endif //_COLLDICH_H

3
src/R_10_00/ab/f127.dir Executable file
View File

@ -0,0 +1,3 @@
127
1
%colldich|0|0|52|20|Collegamento a dichiarazioni per bilanci|||

26
src/R_10_00/ab/f127.trr Executable file
View File

@ -0,0 +1,26 @@
127
22
ID|3|6|0|Identificatore record
F4A|2|3|0|Riferimento riga mod 740/F
F4B|1|1|0|'b' riga bis mod 740/F
P4A|2|3|0|Riferimento prospetto di bilancio Mod.740
P4B|1|1|0|'b' riga bis prospetto di bilancio Mod.740
A5A|2|3|0|Riferimento riga Mod.750/A
A5B|1|1|0|'b' riga bis Mod.750/A
P5A|2|3|0|Riferimento prospetto di bilancio Mod.750
P5B|1|1|0|'b' riga bis prospetto di bilancio Mod.750
A6A|2|3|0|Riferimento riga Mod.760/A
A6B|1|1|0|'b' riga bis Mod.760/A
X4A|2|3|0|Riferimento prospetto dei crediti Mod.740
X4B|1|1|0|'b' riga bis prospetto dei crediti Mod.740
X5A|2|3|0|Riferimento prospetto dei crediti Mod.750
X5B|1|1|0|'b' riga bis prospetto dei crediti Mod.750
X6A|2|3|0|Riferimento prospetto dei crediti Mod.760
X6B|1|1|0|'b' riga bis prospetto dei crediti Mod. 760
P6A|2|3|0|Riferimento prospetto di bilancio Mod. 760
P6B|1|1|0|'b' riga bis prospetto di bilancio Mod. 760
K4A|2|3|0|Riferimento Mod. 740/K
K5A|2|3|0|Riferimento Mod. 750/K
K6A|2|3|0|Riferimento Mod. 760/K
1
ID|

3
src/R_10_00/ab/f78.dir Executable file
View File

@ -0,0 +1,3 @@
78
1
$abpcon|0|0|110|0|Piano dei conti analisi di bilancio|||

12
src/R_10_00/ab/f78.trr Executable file
View File

@ -0,0 +1,12 @@
78
7
CODCBL|1|12|0|Codice piano conti
LIVELLO|2|2|0|
DESCRIZ|1|80|0|Descrizione
INDBIL|2|1|0|Indicatore di bilancio
CODCONTR|1|12|0|Codice piano conti di sezione opposta
SOSPESO|8|1|0|Conto sospeso
DETT|1|1|0|Indicatore di <D>ettaglio/<M>ovimento o altro
2
CODCBL|
UPPER(DESCRIZ)|X

3
src/R_10_00/ab/f79.dir Executable file
View File

@ -0,0 +1,3 @@
79
1
%absaldi|0|0|143|0|Saldi analisi di bilancio|||

17
src/R_10_00/ab/f79.trr Executable file
View File

@ -0,0 +1,17 @@
79
13
CODDITTA|3|5|0|Codice ditta
ANNO|2|4|0|Anno
CODPDB|1|2|0|Codice periodo
TIPOBIL|1|2|0|Codice tipo di bilancio
CODCBL|1|12|0|Codice piano conti
CODCMS|1|20|0|Codice Commessa
FLDA|1|1|0|Flag <D>are o <A>vere
SALDO|4|18|3|Saldo iniziale
PDARE|4|18|3|Progressivi dare
PAVERE|4|18|3|Progressivi avere
RDARE|4|18|3|Riclassificazione dare
RAVERE|4|18|3|Riclassificazione avere
IDMOVDETT|1|6|0|Identificatore eventuale primo dettaglio o movimento
1
CODDITTA+ANNO+CODPDB+TIPOBIL+CODCBL+CODCMS|

3
src/R_10_00/ab/f80.dir Executable file
View File

@ -0,0 +1,3 @@
80
1
%movdett|0|0|421|0|Movimenti / dettagli analisi di bilancio|||

37
src/R_10_00/ab/f80.trr Executable file
View File

@ -0,0 +1,37 @@
80
33
CODDITTA|3|5|0|Codice ditta
ANNO|2|4|0|Anno
CODPDB|1|2|0|Codice periodo
TIPOBIL|1|2|0|Codice tipo di bilancio
CODCBL|1|12|0|Codice piano conti
ID|3|6|0|Identificatore record all' interno del periodo ( >0)
TIPODETT|1|2|0|Tipo dett:<CG>ContoContabile,<Mo>vimento,<Ar>ticolo,<Ce>spite,<An>alitica,<DT>taglio,<CL>iente,<FO>rnitore
CODDETT|1|25|0|Codice Dettaglio
DESCRIZ|1|80|0|Descrizione
FLDA|1|1|0|Flag <D>are, <A>vere
IMPORTO|4|18|3|Importo o saldo iniziale
PDARE|4|18|3|Progressivi dare
PAVERE|4|18|3|Progressivi avere
RDARE|4|18|3|Riclassificazione dare
RAVERE|4|18|3|Riclassificazione avere
DATAREG|5|8|0|Data di registrazione
ANR|1|1|0|
DATADOC|5|8|0|Data documento
NDOC|1|7|0|Numero documento
CAUS|1|3|0|Codice causale
IMMESSO|8|1|0|Immesso (se FALSE trasferito) (era IMTRA)
DETT|1|2|0|Tipo codice dettaglio del figlio (<CG>,<DT>, ...)
INDIR|1|50|0|Indirizzo
LOC|1|50|0|Localitá
PROV|1|2|0|Provincia
CAP|1|5|0|CAP
COFI|1|16|0|Codice Fiscale
STATOPAIV|1|2|0|Stato ISO della partita IVA
PAIV|1|12|0|Partita IVA
IDPADRE|3|6|0|Identificatore padre
IDFIGLIO|3|6|0|Identificatore figlio
IDSUCC|3|6|0|Identificatore successivo
IDPREC|3|6|0|Identificatore precedente
1
CODDITTA+ANNO+CODPDB+TIPOBIL+CODCBL+ID|

3
src/R_10_00/ab/f81.dir Executable file
View File

@ -0,0 +1,3 @@
81
1
%rett|0|0|206|0|Rettifiche analisi di bilancio|||

23
src/R_10_00/ab/f81.trr Executable file
View File

@ -0,0 +1,23 @@
81
17
CODDITTA|3|5|0|Codice Ditta
ANNO|1|4|0|Anno
CODPDB|1|2|0|Codice periodo di bilancio
TIPOBIL|1|2|0|Tipo di bilancio
NUMREG|3|10|0|Numero di registrazione
DATAREG|5|8|0|Data di registrazione
ANR|2|1|0|Anno di riferimento '0' anno di registrazione '1' anno precedente
DESCR|1|50|0|Descrizione
UMS|1|1|0|Unitá di misura
CAUS|1|3|0|Causale
FLDA|1|1|0|Flag <D>are, <A>vere
IMPORTO|4|18|3|Importo
CODCBL|1|12|0|Codice piano conti
IDDM|3|6|0|Identificatore dettaglio / movimento
DSV|1|80|0|Descrizione voce
APERTURA|8|1|0|Movimento d' apertura
RICLASSIF|8|1|0|Movimento di riclassificazione
3
CODDITTA+ANNO+CODPDB+TIPOBIL+NUMREG|
CODDITTA+ANNO+CODPDB+TIPOBIL+DATAREG+NUMREG|X
CODDITTA+ANNO+CODPDB+TIPOBIL+CODCBL+IDDM|X

3
src/R_10_00/ab/f82.dir Executable file
View File

@ -0,0 +1,3 @@
82
1
%analisi|0|0|78|20|Archivio tabelle analisi di bilancio|||

11
src/R_10_00/ab/f82.trr Executable file
View File

@ -0,0 +1,11 @@
82
6
CODAN|1|2|0|Codice analisi
DESCRIZ|1|60|0|Descrizione
TIPOAN|1|1|0|Tipo analisi
PFSTAL|1|2|0|Codice profilo stampa allegati
PFSTRF|1|2|0|Codice profilo stampa raffronti
NOTE|11|10|0|Note
2
CODAN|
UPPER(DESCRIZ)|X

3
src/R_10_00/ab/f83.dir Executable file
View File

@ -0,0 +1,3 @@
83
1
%voci|0|0|123|20|Archivio voci tabelle analisi di bilancio|||

13
src/R_10_00/ab/f83.trr Executable file
View File

@ -0,0 +1,13 @@
83
8
CODVC|1|10|0|Codice voce
DESCRIZ|1|80|0|Descrizione voce
TIPOVC|1|1|0|Tipo voce <T>itolo,< >semplice, <C>omposta, <U>tile/Perdita, <I>ndice
CODCBL|1|12|0|Codice piano conti
INDBIL|1|1|0|Indicatore di bilancio
IDCARADD|1|12|0|Identificatore caratteristiche addizionali
TVL|1|1|0|Tipo valore:S=saldo fin,I=inizio,D=dare,A=avere,V=Dare-Avere
CLASSEVOCE|1|5|0|Classe voce (per IV direttiva)
2
CODVC|
UPPER(DESCRIZ)|X

3
src/R_10_00/ab/f84.dir Executable file
View File

@ -0,0 +1,3 @@
84
1
%relvoci|0|0|190|20|Relazioni voci|||

10
src/R_10_00/ab/f84.trr Executable file
View File

@ -0,0 +1,10 @@
84
6
TIPOCOD|1|1|0|Tipo codice di <V>oce <A>nalisi
CODVC|1|10|0|Codice voce composta o tab. analisi
IDCOMP|3|6|0|Identificatore componente
NEXTCOMP|3|6|0|Identificatore comp. seguente
PREVCOMP|3|6|0|Identificatore comp. precedente
COMP|1|160|0|Componente o formula di voci (con eventuale segno)
1
TIPOCOD+CODVC+IDCOMP|

3
src/R_10_00/ab/f85.dir Executable file
View File

@ -0,0 +1,3 @@
85
1
%relana|0|0|178|20|Relazioni tabelle analisi di bilancio|||

18
src/R_10_00/ab/f85.trr Executable file
View File

@ -0,0 +1,18 @@
85
14
CODAN|1|2|0|Codice analisi
ID|3|9|0|Identificatore
IDPADRE|3|9|0|Identificatore del record $relana padre
IDFIGLIO|3|9|0|Identificatore del record $relana figlio
IDPREC|3|9|0|Identificatore del record $relana successivo
IDSUCC|3|9|0|Identificatore del record $relana precedente
TIPOCOD|1|1|0|Tipo codice voce composta (Analisi/Voce)...
CODVC|1|12|0|...codice voce composta ...
IDCOMP|3|6|0|..e ID componente: sono la chiave per $relvoci
DESCRIZ|1|80|0|Descrizione voce sulla tabella
IDCARADD|1|12|0|Id. caratteristiche addizionali (se =0 usa il default sulle voci)
USACARADD|8|1|0|Flag uso caradd (se FALSE usa comunque caradd di default della voce)
IDCOLDICH|3|6|0|Identificatore collegamento a dichiarazioni
VOCEINCID|1|12|0|Codice voce su cui calcolare l'incidenza
1
CODAN+ID|

3
src/R_10_00/ab/f88.dir Executable file
View File

@ -0,0 +1,3 @@
88
1
%relni|0|0|104|20|Relazioni nota integrativa|||

8
src/R_10_00/ab/f88.trr Executable file
View File

@ -0,0 +1,8 @@
88
4
CODNI|1|10|0|Codice nota integrativa
CODCBL|1|12|0|Codice piano conti
DETT|8|1|0|Dettagliato
DES|1|80|0|Descrizione
1
CODNI+CODCBL|

Some files were not shown because too many files have changed in this diff Show More