Хранение счетов-фактур, которые могут быть или не быть оплачены в тот месяц, когда они должны быть оплачены

Мне нужно разработать программу на C#, где пользователи должны оплачивать счет (с фиксированной суммой) каждый месяц. Некоторые пользователи могут не заплатить в тот же месяц, когда им был отправлен счет, в результате чего возникнут просроченные платежи. Пользователь также должен иметь возможность проверить счет в Интернете по какому-либо идентификатору. Как мне подойти к этому?

Я думал о двух способах, но я не считаю их очень удовлетворительными.

Метод первый

Я создаю таблицу, в которой храню все счета вот так

+----+------+-----------+--------+--------+------------+
| Id | Code | CreatedOn | UserId | Amount |  PaidOn?   |
+----+------+-----------+--------+--------+------------+
|  1 | 1234 | 2018-04-1 |      1 | 100    | null       |
|  2 | 1235 | 2018-05-1 |      1 | 210*   | 2018-05-25 |
+----+------+-----------+--------+--------+------------+

* включает предыдущую сумму, текущую сумму и просроченную комиссию.

В этом случае я кэширую сумму, которую пользователь должен заплатить, и каждый месяц генерирую новый счет. Преимущества этого подхода заключаются в том, что когда пользователь вводит 1234, я могу проверить, не совпадают ли месяц и год, и указать им на самый последний счет, который они должны оплатить.

Также: нужен ли мне какой-то сервис, который генерирует их каждый месяц? Или всякий раз, когда администратор нажимает кнопку создания, я проверяю, существует ли уже счет для пользователя, если я не вставляю его?

Метод второй

Я храню только оплаченные счета. Я могу проверить, когда последний раз был оплачен счет, и отсюда рассчитать причитающуюся сумму. Однако проблема в том, что я не уверен, как мне обращаться с кодом. Поскольку счет-фактура по-прежнему будет печататься каждый первый день каждого месяца и отправляться пользователям, им нужен какой-то ссылочный код.

Одно из решений, которое я подумал, заключалось в том, чтобы иметь столбец GUID в таблице пользователей и использовать этот идентификатор для шифрования даты и времени в этом формате MMyyyy. Создаваемое значение всегда будет уникальным, и мне не нужно его нигде хранить. Поэтому, когда пользователь вводит ссылочный код, я расшифровываю дату и повторно создаю для него счет.

По сути, это все, но по какой-то причине оба эти метода кажутся неправильными.

Как насчет объединения этих двух методов? Вы можете создавать счет в начале каждого месяца, уведомлять пользователя по электронной почте со ссылкой на этот счет, а в следующем месяце (если счет не был оплачен) вы просто обновляете значение суммы и снова уведомляете пользователя. Для этого вам не нужна какая-то служба, просто используйте какой-нибудь планировщик (Cron, Windows Scheduler, Quartz.net и т. д.)

vasily.sib 25.05.2018 05:21

@ vasily.sib В приведенных ниже предложениях не рекомендуется обновлять старые. Вместо этого просто создавайте новые каждый месяц. Спасибо за предоставленные библиотеки, я воспользуюсь комбинацией ответов здесь и информации, которую предоставит их бухгалтер, чтобы придумать определенное решение.

user4433985 25.05.2018 12:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
167
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Я не думаю, что правильно добавлять сумму из предыдущих неоплаченных счетов к новым счетам-фактурам, это не то, как работает кредиторская задолженность. Вы выставляете новые счета-фактуры на новые товары, а затем, если есть неоплаченные счета-фактуры, вы можете выпустить Отчет, подтверждающий это.

Метод 2 лучше, но мне не нравится идея зашифрованной даты. Однажды начальник сказал мне, что налоговые органы ожидают, что номера счетов будут иметь последовательную нумерацию (и именно так работает программное обеспечение, такое как Quick Books). Кроме того, зашифрованные строки будут длинными и громоздкими.

Используйте метод 2, но используйте последовательные номера счетов и сохраняйте все счета, оплаченные или нет, я не вижу недостатков.

Обновлено:

О просроченных платежах (кстати, сайт QB хорош для общих вопросов и ответов по бухгалтерскому учету, например https://community.intuit.com/articles/1145979-can-i-enter-finance-charges-service-charges-or-late-fees-on-customer-invoices)

+----+------+-----------+--------+------------+------------+---------------+
| Id | Code | CreatedOn | UserId | LineAmount |  PaidOn?   | OtherCharges
+----+------+-----------+--------+------------+------------+---------------+
|  1 | 1234 | 2018-04-1 |      1 | 100        | null       |
|  2 | 1235 | 2018-05-1 |      1 | 100        | 2018-05-25 | 10
+----+------+-----------+--------+------------+------------+---------------+

Я думаю, это должно быть больше похоже на это (кстати, вы должны проверить это в будущем, предполагая, что в какой-то момент будет несколько LineAmounts, сделайте это с типичным отношением один ко многим, но для простоты предположите здесь только 1).

Invoice.Id == 1 не был оплачен, поэтому плата за 10 может быть перенесена на Invoice.Id == 2 (всего 110).

Клиент по-прежнему должен оплатить Счет-фактуру 1, потому что Счет-фактура 2 не заменяет его.

Хорошо, поэтому, если я использую второй метод, скажем, я храню счет за этот месяц, а пользователь не платит, должен ли я добавить новый столбец для хранения просроченных сборов и в следующем счете добавить обычную сумму в сумма столбца, а просроченная сумма в соответствующем столбце? Я помечаю все как оплаченные после оплаты окончательного счета?

user4433985 25.05.2018 11:51

@ E.Hoxha Я добавил еще к ответу

Jim W says reinstate Monica 25.05.2018 18:22

Благодарю вас за вашу новость. Эта ссылка и ваш ответ в целом дали мне очень хорошее представление о том, как со всем этим справиться.

user4433985 26.05.2018 16:04

Относитесь к вещам такими, какие они есть:

  1. Счет существует независимо от того, был он оплачен или нет. Это еще один шаг в его жизни. Итак, ваша база данных должна отражать этот факт.

  2. Выставляйте реальный счет за каждый период, который пользователь использовал, и должен заплатить сумму за этот период. То есть в конце каждого месяца.

  3. Как уже указывалось, используйте последовательную нумерацию счетов-фактур, независимо от того, оплачены они или нет.

  4. Создайте еще одну таблицу с именем InvoicePayments, в которой вы будете хранить: InvoiceId | PaymentDateAmount, если вы хотите включить функцию частичных платежей по счету).

  5. Время от времени (в зависимости от того, как часто вы хотите отправлять напоминания) просматривайте таблицу InvoicePayments, проверяйте те, которые подлежат оплате дольше, чем ваша политика, и отправляйте уведомления соответственно.

Не думаю, что мне нужна таблица InvoicePayments, так как частичные платежи не принимаются, все остальное хорошо. Однако как мне обращаться с пени за просрочку платежа? (Я вернусь к более конкретному способу их расчета, если необходимо)

user4433985 25.05.2018 12:16

Это нет проблема программного обеспечения. Пожалуйста, пожалуйста спросите бухгалтера, как обрабатываются счета в вашей стране. Неважно, красивый ли это дизайн базы данных или отличная архитектура программного обеспечения, в первую очередь он должен соответствовать правилам и положениям ваших налоговых органов.

Например, даже мысль об объединении двух счетов-фактур в один заставит налогового бухгалтера побледнеть и молча ускользнет в страну, в которой в моей юрисдикции нет договора об экстрадиции.

Если это домашнее задание, отлично. Выберите один вариант, пусть учитель оценит его и извлечет уроки. Если это реальное программное обеспечение, иди найди профессионала и пусть они выдадут вам требования. Вы разработчик программного обеспечения, неплохо не знать, как работает бухгалтерский учет. Это не наша работа. Но является наша работа - просить о помощи, а не просто подбрасывать ее.

Соберите требования от профессионала в области бухгалтерского учета. потом подумай о своем софте.

На самом деле это не домашнее задание и не «настоящее» программное обеспечение в том смысле, что имеет значение, будет ли оно соответствовать налоговым правилам или нормам. Но я думаю, что вы правы, поэтому я встречусь с их бухгалтером и попрошу их более подробно рассказать, как они хотят обрабатывать свои счета. +1 за «Но наша работа - просить о помощи, а не просто кричать». :П

user4433985 25.05.2018 12:34

Другие вопросы по теме