Skip to content

Commit

Permalink
برمجة وتوحيد دالة تسمية و استرجاع الحسابات
Browse files Browse the repository at this point in the history
  • Loading branch information
vzool committed Oct 9, 2024
1 parent b56d8aa commit 4ace7b3
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 59 deletions.
Binary file modified analysis/database/zakat-pony.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified analysis/database/zakat.pdf
Binary file not shown.
Binary file modified analysis/database/zakat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion analysis/database/zakat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
158 changes: 100 additions & 58 deletions zakat/zakat_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,33 +376,44 @@ def exchanges(self, account: int) -> dict | None:
"""

@abstractmethod
def account(self, name: str, ref: int = None) -> tuple[int, str]:
def account(self, name: str = None, ref: int = None) -> tuple[int, str] | None:
"""
Associates a name with an account number and tracks the relationship.
This function manages accounts, supporting creation, retrieval, and updating.
Parameters:
name (str): The name to associate with the account.
ref (int, optional): The optional reference number for the account.
name (str, optional): The name of the account. If provided and `ref` is not provided,
a new account with this name will be created if it doesn't already exist. Defaults to None.
ref (int, optional): The reference ID of an existing account. If provided and `name` is not provided,
the account with this ID will be retrieved. Defaults to None.
Returns:
tuple[int, str]: A tuple containing the account number and the associated name.
tuple[int, str] | None: A tuple containing the account ID and name if successful,
otherwise None.
Raises:
(Implementation specific exceptions, if any)
This function manages the association between names and account numbers. It creates new accounts if necessary,
and updates existing associations based on the provided name and reference.
The function also tracks the relationship between names and accounts in a dictionary for future reference.
This function performs the following actions based on the provided arguments:
The following actions are performed:
1. **Create Account (name provided, no reference):**
- Checks if an account with the provided name exists.
- If not found, creates a new account with the given name and commits the change to the database.
- Returns a tuple containing the newly created account's ID and name.
1. If the 'name' key doesn't exist in the `self._vault` dictionary, it creates a new entry with 'last_account'
set to 0 and 'account' set to an empty dictionary.
2. If both `name` and `ref` are provided, the function checks if either the name or reference already exists in
the 'account' dictionary. If so, it removes the existing association and creates a new one with the provided
name and reference.
3. If only `name` is provided, the function checks if the name already exists in the 'account' dictionary.
If not, it creates a new account number and associates it with the name.
4. In all cases, the function updates the 'account' dictionary with the new association and calls the `set_name`
function to update the 'name' field in the corresponding account entry.
5. Finally, the function returns a tuple containing the account number and the associated name.
2. **Retrieve Account (reference provided, no name):**
- Attempts to find an account with the provided reference.
- If found, returns a tuple containing the account's ID and name.
- If not found, returns None.
3. **Update Account Name (both name and reference provided):**
- Attempts to find an account with the provided reference.
- If found:
- Checks if the existing name matches the provided name.
- If names differ, updates the account name with the provided name and commits the change.
- Returns a tuple containing the account's ID and updated name (if applicable).
- If not found with the reference, creates a new account with the provided ID and name and
returns the new account information.
"""

@abstractmethod
Expand Down Expand Up @@ -2109,7 +2120,9 @@ def name(self, account: int) -> str | None:
return self._vault['account'][account]['name']
return None

def account(self, name: str, ref: int = None) -> tuple[int, str]:
def account(self, name: str = None, ref: int = None) -> tuple[int, str] | None:
if not name and not ref:
return None
if 'name' not in self._vault:
self._vault['name'] = {
'last_account': 0,
Expand All @@ -2119,31 +2132,34 @@ def account(self, name: str, ref: int = None) -> tuple[int, str]:
def set_name(_account: int, _name: str):
if not self.account_exists(_account):
self.track(account=_account)
self.step(
action=ActionEnum.NAME_ACCOUNT,
account=_account,
value=self._vault['account'][_account]['name'] if 'name' in self._vault['account'][
_account] else None,
key='name',
math_operation=MathOperationEnum.EQUAL,
)
self._vault['account'][_account]['name'] = _name
self.step(
action=ActionEnum.NAME_ACCOUNT,
account=_account,
value=self._vault['account'][_account]['name'] if 'name' in self._vault['account'][
_account] else None,
key='name',
math_operation=MathOperationEnum.EQUAL,
)
self._vault['account'][_account]['name'] = _name
self._vault['name']['account'][_name] = _account
self._vault['name']['account'][_account] = _name

if ref and not name:
if ref not in self._vault['name']['account']:
return None

if name and ref:
if name in self._vault['name']['account']:
old_ref = self._vault['name']['account'][name]
del self._vault['name']['account'][name]
if old_ref in self._vault['name']['account']:
del self._vault['name']['account'][old_ref]
raise 'Name is already used'
if ref in self._vault['name']['account']:
old_name = self._vault['name']['account'][ref]
del self._vault['name']['account'][ref]
if old_name in self._vault['name']['account']:
del self._vault['name']['account'][old_name]
self._vault['name']['account'][name] = ref
self._vault['name']['account'][ref] = name

set_name(ref, name)
return ref, name

if name not in self._vault['name']['account']:
account = self._vault['name']['last_account']
account += 1
Expand Down Expand Up @@ -2505,6 +2521,7 @@ class Account(db.Entity):

class Box(db.Entity):
_table_ = 'box'
id = pony.PrimaryKey(int, auto=True)
account_id = pony.Required(Account)
time = pony.Required(int, unique=True)
record_date = pony.Required(datetime.datetime)
Expand Down Expand Up @@ -2697,23 +2714,37 @@ def exchange(self, account: int, created: int = None, rate: float = None, descri
def exchanges(self, account: int) -> dict | None:
pass

def account(self, name: str, ref: int = None) -> tuple[int, str]:
def account(self, name: str = None, ref: int = None) -> tuple[int, str] | None:
if not name and not ref:
return None
with pony.db_session:
if name:
if name and not ref:
account = Account.get(name=name)
if ref:
account = Account[ref]
if account:
if not account:
account = Account(name=name)
pony.commit()
return account.id, account.name
if ref and not name:
account = Account.get(id=ref)
if not account:
return None
return account.id, account.name
if name and ref:
account = Account.get(id=ref)
if account:
if account.name != name:
account.name = name
return account.id, account.name
account = Account(id=ref, name=name)
return account.id, account.name
account = Account(name=name)
return account.id, account.name

def transfer(self, unscaled_amount: float | int | Decimal, from_account: int, to_account: int, desc: str = '',
created: int = None, debug: bool = False) -> list[int]:
pass

@pony.db_session()
def account_exists(self, account: int) -> bool:
pass
return Account.exists(id=account)

def steps(self) -> dict:
pass
Expand Down Expand Up @@ -2785,17 +2816,23 @@ def export_json(self, path: str = "data.json") -> bool:
def vault(self, section: Vault = Vault.ALL) -> dict:
match section:
case Vault.ACCOUNT:
return Account.select()
return {a.id: a.to_dict(with_lazy=True) for a in Account.select()[:]}
case Vault.NAME:
return Account.select()
account = {}
for k, v in self.vault(Vault.ACCOUNT).items():
account[k] = v['name']
account[v['name']] = k
return {
'account': account,
}
case Vault.HISTORY:
return History.select()
return History.select()[:]
case Vault.REPORT:
return Report.select()
return Report.select()[:]
return {
'account': Account.select(),
'history': History.select(),
'report': Report.select(),
'account': Account.select()[:],
'history': History.select()[:],
'report': Report.select()[:],
}

def snapshot(self) -> bool:
Expand Down Expand Up @@ -3313,8 +3350,6 @@ def _test_core(self, restore=False, debug=False):
if debug:
print(f'index = {index + 1}, ref = {ref}')
assert index + 1 == ref
print(self.db.vault(Vault.ACCOUNT))
#raise 123
assert index + 1 in self.db.vault(Vault.ACCOUNT)
assert name == self.db.vault(Vault.ACCOUNT)[index + 1]['name']
account_z_ref, account_z_name = self.db.account(name='z')
Expand All @@ -3323,17 +3358,24 @@ def _test_core(self, restore=False, debug=False):
account_xz_ref, account_xz_name = self.db.account(name='xz')
assert account_xz_ref == 27
assert account_xz_name == 'xz'
account_z_ref_new, account_z_name_new = self.db.account(name='z', ref=321)
assert self.db.account_exists(account_z_ref_new)
assert account_z_ref_new == 321
assert account_z_name_new == 'z'
assert account_z_ref not in self.db.vault(Vault.NAME)['account']
use_same_account_name_failed = False
assert self.db.account(ref=321) is None
try:
self.db.account(name='z', ref=321)
except:
use_same_account_name_failed = True
assert use_same_account_name_failed
account_zzz_ref_new, account_zzz_name_new = self.db.account(name='zzz', ref=321)
assert self.db.account_exists(account_zzz_ref_new)
assert account_zzz_ref_new == 321
assert account_zzz_name_new == 'zzz'
assert account_z_ref in self.db.vault(Vault.NAME)['account']
assert self.db.account_exists(account_z_ref)
account_zz_ref, account_zz_name = self.db.account(name='zz', ref=321)
assert self.db.account_exists(account_zz_ref)
assert account_zz_ref == 321
assert account_zz_name == 'zz'
assert account_z_name not in self.db.vault(Vault.NAME)['account']
assert account_zzz_name_new not in self.db.vault(Vault.NAME)['account']
account_xx_ref, account_xx_name = self.db.account(name='xx', ref=333)
assert self.db.account_exists(account_xx_ref)
assert account_xx_ref == 333
Expand Down

0 comments on commit 4ace7b3

Please sign in to comment.