diff --git a/README.md b/README.md index 53be6d13..60d67b2b 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,3 @@ -# Installation on Ubuntu 14.04 -## Prepare the system -1. Install system-wide pip -**Currently the ensurepip is broken in Python 3.4 / Ubuntu 14.04, therefore we need to install system-wide pip** -```bash -sudo apt-get install python3-pip -``` - -2. Install postgresql -```bash -sudo apt-get install postgresql postgresql-client pgadmin3 -``` -[Full Guide](https://help.ubuntu.com/community/PostgreSQL) - -3. Configure the server and set password -```bash -sudo -u postgres psql postgres -\password postgres -``` - -4. Install components to build psycopg2 -```bash -sudo apt-get install libpq-dev python3-dev -``` - -## Setup the virutal environment -1. Create the virtual environment -**Currently the ensurepip is broken in Python 3.4 / Ubuntu 14.04, therefore --without-pip is needed.** -```bash -pyvenv-3.4 env --without-pip --system-site-packages -``` - -2. Activate the virtual environment -```bash -source env/bin/activate -``` - -3. Install pyramid, sqlachemy, psycopg2 and other dependencies: -```bash -python3 -m pip install pyramid waitress sqlalchemy zope.sqlalchemy psycopg2 -``` - - ## Prettier - to format typescript files ```npx prettier --write src/app/``` @@ -61,4 +18,4 @@ rm -rf `poetry env info -p` ### Poerty install ```sh poetry install -``` \ No newline at end of file +``` diff --git a/brewman/alembic/env.py b/brewman/alembic/env.py index 6068332c..dffc52b5 100644 --- a/brewman/alembic/env.py +++ b/brewman/alembic/env.py @@ -61,9 +61,7 @@ def run_migrations_online(): ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata, compare_type=True - ) + context.configure(connection=connection, target_metadata=target_metadata, compare_type=True) with context.begin_transaction(): context.run_migrations() diff --git a/brewman/alembic/script.py.mako b/brewman/alembic/script.py.mako new file mode 100644 index 00000000..2c015630 --- /dev/null +++ b/brewman/alembic/script.py.mako @@ -0,0 +1,24 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} +branch_labels = ${repr(branch_labels)} +depends_on = ${repr(depends_on)} + + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"} diff --git a/brewman/alembic/versions/002f51d87565_precision.py b/brewman/alembic/versions/002f51d87565_precision.py new file mode 100644 index 00000000..04ba5d3e --- /dev/null +++ b/brewman/alembic/versions/002f51d87565_precision.py @@ -0,0 +1,291 @@ +"""precision + +Revision ID: 002f51d87565 +Revises: eed0b382c287 +Create Date: 2020-11-03 20:54:33.718750 + +""" +import sqlalchemy as sa + +from alembic import op + + +# revision identifiers, used by Alembic. +revision = "002f51d87565" +down_revision = "eed0b382c287" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column( + "products", + "fraction", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=5), + existing_nullable=False, + ) + op.alter_column( + "products", + "product_yield", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=5), + existing_nullable=False, + ) + op.alter_column( + "products", + "cost_price", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + existing_nullable=False, + ) + op.alter_column( + "products", + "sale_price", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + existing_nullable=False, + ) + op.alter_column( + "recipes", + "quantity", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + existing_nullable=False, + ) + op.alter_column( + "recipes", + "cost_price", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + existing_nullable=False, + ) + op.alter_column( + "recipes", + "sale_price", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + existing_nullable=False, + ) + op.alter_column( + "journals", + "debit", + existing_type=sa.Integer(), + nullable=False, + ) + op.alter_column( + "journals", + "amount", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + nullable=False, + ) + op.alter_column( + "inventories", + "quantity", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + nullable=False, + ) + op.alter_column( + "inventories", + "rate", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + nullable=False, + ) + op.alter_column( + "inventories", + "tax", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=5), + nullable=False, + ) + op.alter_column( + "inventories", + "discount", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=5), + nullable=False, + ) + op.alter_column( + "batches", + "quantity_remaining", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + nullable=False, + ) + op.alter_column( + "batches", + "rate", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=2), + nullable=False, + ) + op.alter_column( + "batches", + "tax", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=5), + nullable=False, + ) + op.alter_column( + "batches", + "discount", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=15, scale=5), + nullable=False, + ) + op.alter_column( + "attendances", + "amount", + existing_type=sa.Numeric(), + type_=sa.Numeric(precision=5, scale=2), + existing_nullable=False, + ) + op.alter_column( + "incentives", + "days_worked", + existing_type=sa.INTEGER(), + type_=sa.Numeric(precision=5, scale=1), + existing_nullable=False, + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column( + "products", + "fraction", + existing_type=sa.Numeric(precision=15, scale=5), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "products", + "product_yield", + existing_type=sa.Numeric(precision=15, scale=5), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "products", + "cost_price", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "products", + "sale_price", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "recipes", + "quantity", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "recipes", + "cost_price", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "recipes", + "sale_price", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "journals", + "debit", + existing_type=sa.Integer(), + nullable=True, + ) + op.alter_column( + "journals", + "amount", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "inventories", + "quantity", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "inventories", + "rate", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "inventories", + "tax", + existing_type=sa.Numeric(precision=15, scale=5), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "inventories", + "discount", + existing_type=sa.Numeric(precision=15, scale=5), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "batches", + "quantity_remaining", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "batches", + "rate", + existing_type=sa.Numeric(precision=15, scale=2), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "batches", + "tax", + existing_type=sa.Numeric(precision=15, scale=5), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "batches", + "discount", + existing_type=sa.Numeric(precision=15, scale=5), + type_=sa.Numeric(), + nullable=True, + ) + op.alter_column( + "attendances", + "amount", + existing_type=sa.Numeric(precision=5, scale=2), + type_=sa.Numeric(), + existing_nullable=False, + ) + op.alter_column( + "incentives", + "days_worked", + existing_type=sa.Numeric(precision=5, scale=1), + type_=sa.INTEGER(), + existing_nullable=False, + ) + # ### end Alembic commands ### diff --git a/brewman/alembic/versions/0bf3d70ee7de_initial_commit.py b/brewman/alembic/versions/0bf3d70ee7de_initial_commit.py index 3113960d..ee835afa 100644 --- a/brewman/alembic/versions/0bf3d70ee7de_initial_commit.py +++ b/brewman/alembic/versions/0bf3d70ee7de_initial_commit.py @@ -126,9 +126,7 @@ def upgrade(): name=op.f("fk_auth_login_history_user_id_auth_users"), ), sa.PrimaryKeyConstraint("login_history_id", name=op.f("pk_auth_login_history")), - sa.UniqueConstraint( - "user_id", "client_id", "date", name=op.f("uq_auth_login_history_user_id") - ), + sa.UniqueConstraint("user_id", "client_id", "date", name=op.f("uq_auth_login_history_user_id")), ) op.create_table( "auth_rolegroups", @@ -199,9 +197,7 @@ def upgrade(): sa.Column("ServicePoints", sa.Numeric(precision=5, scale=2), nullable=True), sa.Column("JoiningDate", sa.DateTime(), nullable=True), sa.Column("LeavingDate", sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint( - ["id"], ["accounts.id"], name=op.f("fk_employees_id_accounts") - ), + sa.ForeignKeyConstraint(["id"], ["accounts.id"], name=op.f("fk_employees_id_accounts")), sa.PrimaryKeyConstraint("id", name=op.f("pk_employees")), ) op.create_table( @@ -229,9 +225,7 @@ def upgrade(): ), sa.PrimaryKeyConstraint("JournalID", name=op.f("pk_journals")), ) - op.create_index( - op.f("ix_journals_VoucherID"), "journals", ["VoucherID"], unique=False - ) + op.create_index(op.f("ix_journals_VoucherID"), "journals", ["VoucherID"], unique=False) op.create_table( "products", sa.Column("ProductID", postgresql.UUID(), nullable=False), @@ -400,13 +394,9 @@ def upgrade(): name=op.f("fk_inventories_VoucherID_vouchers"), ), sa.PrimaryKeyConstraint("InventoryID", name=op.f("pk_inventories")), - sa.UniqueConstraint( - "VoucherID", "BatchID", name=op.f("uq_inventories_VoucherID") - ), - ) - op.create_index( - op.f("ix_inventories_VoucherID"), "inventories", ["VoucherID"], unique=False + sa.UniqueConstraint("VoucherID", "BatchID", name=op.f("uq_inventories_VoucherID")), ) + op.create_index(op.f("ix_inventories_VoucherID"), "inventories", ["VoucherID"], unique=False) op.create_table( "recipe_items", sa.Column("recipe_item_id", postgresql.UUID(), nullable=False), @@ -425,9 +415,7 @@ def upgrade(): name=op.f("fk_recipe_items_recipe_id_recipes"), ), sa.PrimaryKeyConstraint("recipe_item_id", name=op.f("pk_recipe_items")), - sa.UniqueConstraint( - "recipe_id", "product_id", name=op.f("uq_recipe_items_recipe_id") - ), + sa.UniqueConstraint("recipe_id", "product_id", name=op.f("uq_recipe_items_recipe_id")), ) # ### end Alembic commands ### diff --git a/brewman/alembic/versions/eed0b382c287_lowercase_fastapi.py b/brewman/alembic/versions/eed0b382c287_lowercase_fastapi.py index 1d96068b..33863e56 100644 --- a/brewman/alembic/versions/eed0b382c287_lowercase_fastapi.py +++ b/brewman/alembic/versions/eed0b382c287_lowercase_fastapi.py @@ -54,9 +54,7 @@ def upgrade(): batch_op.alter_column("UserID", new_column_name="user_id") batch_op.alter_column("AttendanceType", new_column_name="attendance_type") batch_op.alter_column("CreationDate", new_column_name="creation_date") - batch_op.alter_column( - "Date", new_column_name="date", type_=sa.Date(), nullable=False - ) + batch_op.alter_column("Date", new_column_name="date", type_=sa.Date(), nullable=False) batch_op.alter_column("EmployeeID", new_column_name="employee_id") batch_op.alter_column("AttendanceID", new_column_name="id") batch_op.alter_column("IsValid", new_column_name="is_valid") @@ -70,9 +68,7 @@ def upgrade(): with op.batch_alter_table("batches") as batch_op: batch_op.alter_column("BatchID", new_column_name="id") batch_op.alter_column("Discount", new_column_name="discount") - batch_op.alter_column( - "Name", new_column_name="name", type_=sa.Date(), nullable=False - ) + batch_op.alter_column("Name", new_column_name="name", type_=sa.Date(), nullable=False) batch_op.alter_column("ProductID", new_column_name="product_id") batch_op.alter_column("QuantityRemaining", new_column_name="quantity_remaining") batch_op.alter_column("Rate", new_column_name="rate") @@ -145,9 +141,7 @@ def upgrade(): op.rename_table("service_charges", "incentives") with op.batch_alter_table("employees") as batch_op: - batch_op.alter_column( - "Designation", new_column_name="designation", nullable=False - ) + batch_op.alter_column("Designation", new_column_name="designation", nullable=False) batch_op.alter_column("Salary", new_column_name="salary", nullable=False) batch_op.alter_column("ServicePoints", new_column_name="points", nullable=False) batch_op.alter_column( @@ -184,46 +178,28 @@ def upgrade(): "auth_login_history", type_="unique", ) - op.create_unique_constraint( - op.f("uq_auth_permissions_name"), "auth_permissions", ["name"] - ) + op.create_unique_constraint(op.f("uq_auth_permissions_name"), "auth_permissions", ["name"]) op.drop_constraint("auth_roles_Name_key", "auth_permissions", type_="unique") op.create_unique_constraint(op.f("uq_auth_roles_name"), "auth_roles", ["name"]) op.drop_constraint("auth_groups_Name_key", "auth_roles", type_="unique") - op.create_unique_constraint( - op.f("uq_auth_users_username"), "auth_users", ["username"] - ) + op.create_unique_constraint(op.f("uq_auth_users_username"), "auth_users", ["username"]) op.drop_constraint("auth_users_Name_key", "auth_users", type_="unique") op.create_unique_constraint(op.f("uq_cost_centres_name"), "cost_centres", ["name"]) op.drop_constraint("entities_costcenters_Name_key", "cost_centres", type_="unique") op.drop_constraint("uq_employee_id_date", "fingerprints", type_="unique") - op.create_index( - op.f("ix_inventories_voucher_id"), "inventories", ["voucher_id"], unique=False - ) - op.create_unique_constraint( - op.f("uq_inventories_voucher_id"), "inventories", ["voucher_id", "batch_id"] - ) + op.create_index(op.f("ix_inventories_voucher_id"), "inventories", ["voucher_id"], unique=False) + op.create_unique_constraint(op.f("uq_inventories_voucher_id"), "inventories", ["voucher_id", "batch_id"]) op.drop_index("ix_inventories_VoucherID", table_name="inventories") - op.create_index( - op.f("ix_journals_voucher_id"), "journals", ["voucher_id"], unique=False - ) + op.create_index(op.f("ix_journals_voucher_id"), "journals", ["voucher_id"], unique=False) op.drop_index("ix_journals_VoucherID", table_name="journals") - op.create_unique_constraint( - op.f("uq_product_groups_name"), "product_groups", ["name"] - ) - op.drop_constraint( - "entities_productgroups_Name_key", "product_groups", type_="unique" - ) + op.create_unique_constraint(op.f("uq_product_groups_name"), "product_groups", ["name"]) + op.drop_constraint("entities_productgroups_Name_key", "product_groups", type_="unique") op.create_unique_constraint(op.f("uq_products_code"), "products", ["code"]) op.create_unique_constraint(op.f("uq_products_name"), "products", ["name", "units"]) op.drop_constraint("products_Code_key", "products", type_="unique") op.drop_constraint("products_Name_Units_key", "products", type_="unique") - op.create_unique_constraint( - op.f("uq_recipe_items_recipe_id"), "recipe_items", ["recipe_id", "product_id"] - ) - op.drop_constraint( - "recipe_items_recipe_id_product_id_key", "recipe_items", type_="unique" - ) + op.create_unique_constraint(op.f("uq_recipe_items_recipe_id"), "recipe_items", ["recipe_id", "product_id"]) + op.drop_constraint("recipe_items_recipe_id_product_id_key", "recipe_items", type_="unique") op.create_unique_constraint(op.f("uq_settings_name"), "settings", ["name"]) op.drop_constraint("settings_Name_key", "settings", type_="unique") op.create_index(op.f("ix_vouchers_date"), "vouchers", ["date"], unique=False) @@ -241,12 +217,8 @@ def upgrade(): ["voucher_id"], ["id"], ) - op.drop_constraint( - "service_charges_journal_id_fkey", "incentives", type_="foreignkey" - ) - op.drop_constraint( - "service_charges_voucher_id_fkey", "incentives", type_="foreignkey" - ) + op.drop_constraint("service_charges_journal_id_fkey", "incentives", type_="foreignkey") + op.drop_constraint("service_charges_voucher_id_fkey", "incentives", type_="foreignkey") op.create_foreign_key( "fk_employee_benefit_journal_id_journals", "employee_benefit", @@ -266,13 +238,9 @@ def upgrade(): "employee_benefit", type_="foreignkey", ) - op.drop_constraint( - "salary_deductions_VoucherID_fkey", "employee_benefit", type_="foreignkey" - ) + op.drop_constraint("salary_deductions_VoucherID_fkey", "employee_benefit", type_="foreignkey") - permission = table( - "auth_permissions", column("id", postgresql.UUID()), column("name", sa.String) - ) + permission = table("auth_permissions", column("id", postgresql.UUID()), column("name", sa.String)) op.execute( permission.update() .where(permission.c.name == op.inline_literal("Service Charge")) @@ -290,9 +258,7 @@ def upgrade(): .values({"name": op.inline_literal("Incentives")}) ) # Remove unneeded Payment and Receipt permissions - permission = table( - "auth_permissions", column("id", postgresql.UUID()), column("name", sa.String) - ) + permission = table("auth_permissions", column("id", postgresql.UUID()), column("name", sa.String)) role_permission = table( "role_permissions", column("permission_id", postgresql.UUID()), diff --git a/brewman/brewman/models/master.py b/brewman/brewman/models/master.py index af16728a..b47b09d8 100644 --- a/brewman/brewman/models/master.py +++ b/brewman/brewman/models/master.py @@ -28,9 +28,9 @@ class Product(Base): code = Column("code", Integer, unique=True) name = Column("name", Unicode(255), nullable=False) units = Column("units", Unicode(255), nullable=False) - fraction = Column("fraction", Numeric, nullable=False) + fraction = Column("fraction", Numeric(precision=15, scale=5), nullable=False) fraction_units = Column("fraction_units", Unicode(255), nullable=False) - product_yield = Column("product_yield", Numeric, nullable=False) + product_yield = Column("product_yield", Numeric(precision=15, scale=5), nullable=False) product_group_id = Column( "product_group_id", UUID(as_uuid=True), @@ -38,8 +38,8 @@ class Product(Base): nullable=False, ) account_id = Column("account_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False) - price = Column("cost_price", Numeric, nullable=False) - sale_price = Column("sale_price", Numeric, nullable=False) + price = Column("cost_price", Numeric(precision=15, scale=2), nullable=False) + sale_price = Column("sale_price", Numeric(precision=15, scale=2), nullable=False) is_active = Column("is_active", Boolean, nullable=False) is_fixture = Column("is_fixture", Boolean, nullable=False) is_purchased = Column("is_purchased", Boolean, nullable=False) @@ -127,9 +127,9 @@ class Recipe(Base): id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False) - quantity = Column("quantity", Numeric, nullable=False) - cost_price = Column("cost_price", Numeric, nullable=False) - sale_price = Column("sale_price", Numeric, nullable=False) + quantity = Column("quantity", Numeric(precision=15, scale=2), nullable=False) + cost_price = Column("cost_price", Numeric(precision=15, scale=2), nullable=False) + sale_price = Column("sale_price", Numeric(precision=15, scale=2), nullable=False) notes = Column("notes", Unicode(255)) valid_from = Column("valid_from", Date, nullable=False) diff --git a/brewman/brewman/models/voucher.py b/brewman/brewman/models/voucher.py index 7df7de72..55130cdf 100644 --- a/brewman/brewman/models/voucher.py +++ b/brewman/brewman/models/voucher.py @@ -151,8 +151,8 @@ class Journal(Base): __tablename__ = "journals" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) - debit = Column("debit", Integer) - amount = Column("amount", Numeric) + debit = Column("debit", Integer, nullable=False) + amount = Column("amount", Numeric(precision=15, scale=2), nullable=False) voucher_id = Column( "voucher_id", UUID(as_uuid=True), @@ -289,10 +289,10 @@ class Inventory(Base): ) product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False) batch_id = Column("batch_id", UUID(as_uuid=True), ForeignKey("batches.id"), nullable=False) - quantity = Column("quantity", Numeric) - rate = Column("rate", Numeric) - tax = Column("tax", Numeric) - discount = Column("discount", Numeric) + quantity = Column("quantity", Numeric(precision=15, scale=2), nullable=False) + rate = Column("rate", Numeric(precision=15, scale=2), nullable=False) + tax = Column("tax", Numeric(precision=15, scale=5), nullable=False) + discount = Column("discount", Numeric(precision=15, scale=5), nullable=False) voucher = relationship("Voucher", back_populates="inventories") @@ -335,10 +335,10 @@ class Batch(Base): id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Date, nullable=False) product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False) - quantity_remaining = Column("quantity_remaining", Numeric) - rate = Column("rate", Numeric) - tax = Column("tax", Numeric) - discount = Column("discount", Numeric) + quantity_remaining = Column("quantity_remaining", Numeric(precision=15, scale=2), nullable=False) + rate = Column("rate", Numeric(precision=15, scale=2), nullable=False) + tax = Column("tax", Numeric(precision=15, scale=5), nullable=False) + discount = Column("discount", Numeric(precision=15, scale=5), nullable=False) inventories = relationship("Inventory", backref="batch", cascade=None, cascade_backrefs=False) @@ -390,7 +390,7 @@ class Attendance(Base): employee_id = Column("employee_id", UUID(as_uuid=True), ForeignKey("employees.id")) date = Column("date", Date, nullable=False) attendance_type = Column("attendance_type", Integer) - amount = Column("amount", Numeric) + amount = Column("amount", Numeric(precision=5, scale=2)) creation_date = Column("creation_date", DateTime(timezone=True)) user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id")) is_valid = Column("is_valid", Boolean) diff --git a/brewman/brewman/routers/batch.py b/brewman/brewman/routers/batch.py index 9f94e1ed..72fd0b61 100644 --- a/brewman/brewman/routers/batch.py +++ b/brewman/brewman/routers/batch.py @@ -40,10 +40,10 @@ def batch_term( { "id": item.id, "name": text, - "quantityRemaining": item.quantity_remaining, - "rate": item.rate, - "tax": item.tax, - "discount": item.discount, + "quantityRemaining": round(item.quantity_remaining, 2), + "rate": round(item.rate, 2), + "tax": round(item.tax, 5), + "discount": round(item.discount, 5), "product": { "id": item.product.id, "name": item.product.name, diff --git a/brewman/brewman/routers/reports/daybook.py b/brewman/brewman/routers/reports/daybook.py index 33576835..1bbc1a9f 100644 --- a/brewman/brewman/routers/reports/daybook.py +++ b/brewman/brewman/routers/reports/daybook.py @@ -1,4 +1,5 @@ -import datetime +from datetime import date, datetime +from typing import List import brewman.schemas.reports as schemas @@ -28,12 +29,12 @@ def get_db() -> Session: def report_blank( request: Request, user: UserToken = Security(get_user, scopes=["daybook"]), -): - return { - "startDate": get_start_date(request.session), - "finishDate": get_finish_date(request.session), - "body": [], - } +) -> schemas.Daybook: + return schemas.Daybook( + startDate=get_start_date(request.session), + finishDate=get_finish_date(request.session), + body=[], + ) @router.get("/{start}/{finish}", response_model=schemas.Daybook) @@ -43,20 +44,22 @@ def report_data( request: Request, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["daybook"]), -): - body = build_report(start, finish, db) +) -> schemas.Daybook: + start_date = datetime.strptime(start, "%d-%b-%Y") + finish_date = datetime.strptime(finish, "%d-%b-%Y") + body = build_report(start_date, finish_date, db) set_period(start, finish, request.session) - return {"startDate": start, "finishDate": finish, "body": body} + return schemas.Daybook(startDate=start_date, finishDate=finish_date, body=body) -def build_report(start_date, finish_date, db): +def build_report(start_date: date, finish_date: date, db: Session) -> List[schemas.DaybookItem]: body = [] query = ( db.query(Voucher) .options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True)) - .filter(Voucher.date >= datetime.datetime.strptime(start_date, "%d-%b-%Y")) - .filter(Voucher.date <= datetime.datetime.strptime(finish_date, "%d-%b-%Y")) + .filter(Voucher.date >= start_date) + .filter(Voucher.date <= finish_date) .filter(Voucher.type != VoucherType.by_name("Issue").id) .order_by(Voucher.date) .order_by(Voucher.last_edit_date) @@ -79,21 +82,21 @@ def build_report(start_date, finish_date, db): name_credit = name_credit[:-3] body.append( - { - "id": voucher.id, - "date": voucher.date.strftime("%d-%b-%Y"), - "url": [ + schemas.DaybookItem( + id=voucher.id, + date=voucher.date.strftime("%d-%b-%Y"), + url=[ "/", VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(), str(voucher.id), ], - "type": VoucherType.by_id(voucher.type).name, - "narration": voucher.narration, - "posted": voucher.posted, - "debitText": name_debit, - "debitAmount": debit, - "creditText": name_credit, - "creditAmount": credit, - } + type=VoucherType.by_id(voucher.type).name, + narration=voucher.narration, + posted=voucher.posted, + debitText=name_debit, + debitAmount=debit, + creditText=name_credit, + creditAmount=credit, + ) ) return body diff --git a/brewman/brewman/routers/reports/unposted.py b/brewman/brewman/routers/reports/unposted.py index 315bc08e..6e7ce6b7 100644 --- a/brewman/brewman/routers/reports/unposted.py +++ b/brewman/brewman/routers/reports/unposted.py @@ -28,11 +28,11 @@ def report_data( request: Request, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["post-vouchers"]), -): +) -> List[schemas.Unposted]: return build_report(db) -def build_report(db: Session): +def build_report(db: Session) -> List[schemas.Unposted]: body = [] query = ( @@ -61,21 +61,21 @@ def build_report(db: Session): name_credit = name_credit[:-3] body.append( - { - "id": voucher.id, - "date": voucher.date.strftime("%d-%b-%Y"), - "url": [ + schemas.Unposted( + id=voucher.id, + date=voucher.date.strftime("%d-%b-%Y"), + url=[ "/", VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(), str(voucher.id), ], - "type": VoucherType.by_id(voucher.type).name, - "narration": voucher.narration, - "debitName": name_debit, - "debitAmount": debit, - "creditName": name_credit, - "creditAmount": credit, - } + type=VoucherType.by_id(voucher.type).name, + narration=voucher.narration, + debitName=name_debit, + debitAmount=debit, + creditName=name_credit, + creditAmount=credit, + ) ) return body diff --git a/brewman/brewman/schemas/reports.py b/brewman/brewman/schemas/reports.py index f4aa054e..ee259ae4 100644 --- a/brewman/brewman/schemas/reports.py +++ b/brewman/brewman/schemas/reports.py @@ -164,9 +164,9 @@ class DaybookItem(BaseModel): type_: str narration: str debit_text: Optional[str] - debit: Optional[Decimal] = Field(multiple_of=0.01) + debit_amount: Optional[Decimal] credit_text: Optional[str] - credit: Optional[Decimal] = Field(multiple_of=0.01) + credit_amount: Optional[Decimal] posted: bool @validator("date_", pre=True) diff --git a/Dockerfile b/docker/app/Dockerfile similarity index 100% rename from Dockerfile rename to docker/app/Dockerfile diff --git a/overlord/src/app/settings/settings.component.ts b/overlord/src/app/settings/settings.component.ts index a228efd5..628d6106 100644 --- a/overlord/src/app/settings/settings.component.ts +++ b/overlord/src/app/settings/settings.component.ts @@ -7,7 +7,7 @@ import * as moment from 'moment'; import { Observable, of as observableOf } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators'; -import {environment} from "../../environments/environment"; +import { environment } from '../../environments/environment'; import { AuthService } from '../auth/auth.service'; import { Product } from '../core/product'; import { ToasterService } from '../core/toaster.service'; diff --git a/overlord/src/app/user/user-detail/user-detail.component.ts b/overlord/src/app/user/user-detail/user-detail.component.ts index 8056ea37..178c0957 100644 --- a/overlord/src/app/user/user-detail/user-detail.component.ts +++ b/overlord/src/app/user/user-detail/user-detail.component.ts @@ -70,15 +70,27 @@ export class UserDetailComponent implements OnInit, AfterViewInit { } save() { - this.ser.saveOrUpdate(this.getItem()).subscribe( - () => { - this.toaster.show('Success', ''); - this.router.navigateByUrl('/users'); - }, - (error) => { - this.toaster.show('Danger', error); - }, - ); + if (this.route.snapshot.paramMap.get('id') === 'me') { + this.ser.updateMe(this.getItem()).subscribe( + () => { + this.toaster.show('Success', ''); + this.router.navigateByUrl('/'); + }, + (error) => { + this.toaster.show('Danger', error); + }, + ); + } else { + this.ser.saveOrUpdate(this.getItem()).subscribe( + () => { + this.toaster.show('Success', ''); + this.router.navigateByUrl('/users'); + }, + (error) => { + this.toaster.show('Danger', error); + }, + ); + } } delete() { diff --git a/overlord/src/app/user/user.service.ts b/overlord/src/app/user/user.service.ts index 09887569..b7b6bc78 100644 --- a/overlord/src/app/user/user.service.ts +++ b/overlord/src/app/user/user.service.ts @@ -59,6 +59,14 @@ export class UserService { ); } + updateMe(user: User): Observable { + return >( + this.http + .put(`${url}/me`, user, httpOptions) + .pipe(catchError(this.log.handleError(serviceName, 'update'))) + ); + } + saveOrUpdate(user: User): Observable { if (!user.id) { return this.save(user);